Top Banner
阿里云 IoT Link Rack 一体机 开发指南 产品版本:V1.0.0 文档版本:20200417
915

阿里云IoT Link Rack 一体机

May 09, 2023

Download

Documents

Khang Minh
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 阿里云IoT Link Rack 一体机

阿里云IoT Link Rack 一体机

开发指南

产品版本:V1.0.0

文档版本:20200417

Page 2: 阿里云IoT Link Rack 一体机

开发指南 /  法律声明

法律声明阿里云提醒您在阅读或使用本文档之前仔细阅读、充分理解本法律声明各条款的内容。如果您阅读或

使用本文档,您的阅读或使用行为将被视为对本声明全部内容的认可。

1. 您应当通过阿里云网站或阿里云提供的其他授权通道下载、获取本文档,且仅能用于自身的合法

合规的业务活动。本文档的内容视为阿里云的保密信息,您应当严格遵守保密义务;未经阿里云

事先书面同意,您不得向任何第三方披露本手册内容或提供给任何第三方使用。

2. 未经阿里云事先书面许可,任何单位、公司或个人不得擅自摘抄、翻译、复制本文档内容的部分

或全部,不得以任何方式或途径进行传播和宣传。

3. 由于产品版本升级、调整或其他原因,本文档内容有可能变更。阿里云保留在没有任何通知或者

提示下对本文档的内容进行修改的权利,并在阿里云授权通道中不时发布更新后的用户文档。您

应当实时关注用户文档的版本变更并通过阿里云授权渠道下载、获取最新版的用户文档。

4. 本文档仅作为用户使用阿里云产品及服务的参考性指引,阿里云以产品及服务的“现状”、“有

缺陷”和“当前功能”的状态提供本文档。阿里云在现有技术的基础上尽最大努力提供相应的介

绍及操作指引,但阿里云在此明确声明对本文档内容的准确性、完整性、适用性、可靠性等不作

任何明示或暗示的保证。任何单位、公司或个人因为下载、使用或信赖本文档而发生任何差错或

经济损失的,阿里云不承担任何法律责任。在任何情况下,阿里云均不对任何间接性、后果性、

惩戒性、偶然性、特殊性或刑罚性的损害,包括用户使用或信赖本文档而遭受的利润损失,承担

责任(即使阿里云已被告知该等损失的可能性)。

5. 阿里云文档中所有内容,包括但不限于图片、架构设计、页面布局、文字描述,均由阿里云和/或

其关联公司依法拥有其知识产权,包括但不限于商标权、专利权、著作权、商业秘密等。非经阿

里云和/或其关联公司书面同意,任何人不得擅自使用、修改、复制、公开传播、改变、散布、发

行或公开发表阿里云网站、产品程序或内容。此外,未经阿里云事先书面同意,任何人不得为了

任何营销、广告、促销或其他目的使用、公布或复制阿里云的名称(包括但不限于单独为或以组

合形式包含“阿里云”、“Aliyun”、“万网”等阿里云和/或其关联公司品牌,上述品牌的附属

标志及图案或任何类似公司名称、商号、商标、产品或服务名称、域名、图案标示、标志、标识

或通过特定描述使第三方能够识别阿里云和/或其关联公司)。

6. 如若发现本文档存在任何错误,请与阿里云取得直接联系。

文档版本:20200417 I

Page 3: 阿里云IoT Link Rack 一体机

开发指南 /  通用约定

通用约定

格式 说明 样例

该类警示信息将导致系统重大变更甚至故障,或者导致人身伤害等结果。 禁止:

重置操作将丢失用户配置数据。

该类警示信息可能会导致系统重大变更甚至故障,或者导致人身伤害等结果。 警告:

重启操作将导致业务中断,恢复业务时间约十分钟。

用于警示信息、补充说明等,是用户必须了解的内容。 注意:

权重设置为0,该服务器不会再接受新请求。

用于补充说明、最佳实践、窍门等,不是用户必须了解的内容。 说明:

您也可以通过按Ctrl + A选中全部文件。

> 多级菜单递进。 单击设置 > 网络 > 设置网络类型。

粗体 表示按键、菜单、页面名称等UI元素。 在结果确认页面,单击确定。

Courier字体 命令。 执行cd /d C:/window命令,进入Windows系统文件夹。

斜体 表示参数、变量。 bae log list --instanceid

Instance_ID

[]或者[a|b] 表示可选项,至多选择一个。 ipconfig [-all|-t]

{}或者{a|b} 表示必选项,至多选择一个。 switch {active|stand}

文档版本:20200417 I

Page 4: 阿里云IoT Link Rack 一体机

开发指南 /  目录

目录

法律声明...................................................................................... I通用约定...................................................................................... I1 物联网平台............................................................................... 1

1.1 云端开发指南........................................................................................................... 11.1.1 云端SDK参考................................................................................................11.1.1.1 下载云端SDK............................................................................................. 11.1.1.2 Java SDK使用说明..................................................................................... 21.1.1.3 Python SDK使用说明.................................................................................31.1.1.4 PHP SDK使用说明..................................................................................... 41.1.1.5 .NET SDK使用说明.................................................................................... 61.1.2 云端API参考................................................................................................ 71.1.2.1 API列表.................................................................................................... 71.1.2.2 概述....................................................................................................... 111.1.2.3 调用API..................................................................................................121.1.2.4 公共参数................................................................................................ 131.1.2.5 错误码....................................................................................................141.1.2.6 产品管理................................................................................................ 301.1.2.6.1 CreateProduct.....................................................................................301.1.2.6.2 QueryProduct..................................................................................... 331.1.2.6.3 QueryProductList................................................................................351.1.2.6.4 UpdateProduct................................................................................... 391.1.2.6.5 DeleteProduct.................................................................................... 401.1.2.6.6 CreateProductTags............................................................................. 411.1.2.6.7 UpdateProductTags............................................................................421.1.2.6.8 DeleteProductTags............................................................................. 441.1.2.6.9 ListProductTags.................................................................................. 451.1.2.6.10 ListProductByTags............................................................................. 471.1.2.7 设备管理.................................................................................................491.1.2.7.1 RegisterDevice.....................................................................................491.1.2.7.2 QueryDeviceDetail.............................................................................. 521.1.2.7.3 BatchQueryDeviceDetail..................................................................... 551.1.2.7.4 QueryDevice....................................................................................... 581.1.2.7.5 DeleteDevice.......................................................................................611.1.2.7.6 GetDeviceStatus..................................................................................631.1.2.7.7 BatchGetDeviceState...........................................................................651.1.2.7.8 DisableThing.......................................................................................681.1.2.7.9 EnableThing........................................................................................691.1.2.7.10 BatchCheckDeviceNames.................................................................. 711.1.2.7.11 BatchRegisterDeviceWithApplyId.......................................................731.1.2.7.12 BatchRegisterDevice..........................................................................74

II 文档版本:20200417

Page 5: 阿里云IoT Link Rack 一体机

开发指南 /  目录

1.1.2.7.13 BatchUpdateDeviceNickname........................................................... 761.1.2.7.14 QueryBatchRegisterDeviceStatus.......................................................791.1.2.7.15 QueryPageByApplyId.........................................................................811.1.2.7.16 QueryDeviceEventData...................................................................... 831.1.2.7.17 QueryDevicePropertyData................................................................. 881.1.2.7.18 QueryDevicePropertiesData...............................................................911.1.2.7.19 QueryDeviceServiceData....................................................................961.1.2.7.20 InvokeThingService........................................................................... 991.1.2.7.21 InvokeThingsService........................................................................1021.1.2.7.22 GetGatewayBySubDevice................................................................ 1041.1.2.7.23 QueryDevicePropertyStatus.............................................................1071.1.2.7.24 SetDeviceProperty...........................................................................1091.1.2.7.25 SetDevicesProperty......................................................................... 1121.1.2.7.26 QueryDeviceProp............................................................................ 1131.1.2.7.27 SaveDeviceProp.............................................................................. 1141.1.2.7.28 DeleteDeviceProp............................................................................1171.1.2.7.29 QueryDeviceByTags.........................................................................1181.1.2.7.30 GetThingTopo..................................................................................1211.1.2.7.31 NotifyAddThingTopo....................................................................... 1231.1.2.7.32 RemoveThingTopo...........................................................................1261.1.2.7.33 QueryDeviceStatistics......................................................................1281.1.2.7.34 SetDeviceDesiredProperty............................................................... 1291.1.2.7.35 QueryDeviceDesiredProperty.......................................................... 1331.1.2.7.36 QueryDeviceFileList......................................................................... 1361.1.2.7.37 QueryDeviceFile.............................................................................. 1391.1.2.7.38 DeleteDeviceFile............................................................................. 1411.1.2.8 分组管理...............................................................................................1421.1.2.8.1 CreateDeviceGroup........................................................................... 1421.1.2.8.2 UpdateDeviceGroup......................................................................... 1441.1.2.8.3 DeleteDeviceGroup...........................................................................1451.1.2.8.4 BatchAddDeviceGroupRelations....................................................... 1461.1.2.8.5 BatchDeleteDeviceGroupRelations................................................... 1471.1.2.8.6 QueryDeviceGroupInfo..................................................................... 1491.1.2.8.7 QueryDeviceGroupList...................................................................... 1511.1.2.8.8 SetDeviceGroupTags.........................................................................1541.1.2.8.9 QueryDeviceGroupTagList.................................................................1561.1.2.8.10 QueryDeviceGroupByDevice............................................................1571.1.2.8.11 QuerySuperDeviceGroup.................................................................1591.1.2.8.12 QueryDeviceListByDeviceGroup...................................................... 1601.1.2.8.13 QueryDeviceGroupByTags............................................................... 1631.1.2.9 Topic管理............................................................................................. 1651.1.2.9.1 CreateProductTopic...........................................................................1651.1.2.9.2 UpdateProductTopic......................................................................... 1661.1.2.9.3 QueryProductTopic........................................................................... 1681.1.2.9.4 DeleteProductTopic.......................................................................... 170

文档版本:20200417 III

Page 6: 阿里云IoT Link Rack 一体机

开发指南 /  目录

1.1.2.9.5 CreateTopicRouteTable..................................................................... 1711.1.2.9.6 DeleteTopicRouteTable..................................................................... 1721.1.2.9.7 QueryTopicReverseRouteTable.......................................................... 1731.1.2.9.8 QueryTopicRouteTable...................................................................... 1751.1.2.10 规则引擎............................................................................................. 1761.1.2.10.1 CreateRule.......................................................................................1761.1.2.10.2 CreateRuleAction............................................................................ 1801.1.2.10.3 DeleteRule...................................................................................... 1831.1.2.10.4 DeleteRuleAction............................................................................ 1841.1.2.10.5 GetRule........................................................................................... 1851.1.2.10.6 GetRuleAction................................................................................. 1871.1.2.10.7 ListRule........................................................................................... 1891.1.2.10.8 ListRuleActions................................................................................1921.1.2.10.9 StartRule......................................................................................... 1941.1.2.10.10 StopRule........................................................................................1951.1.2.10.11 UpdateRule................................................................................... 1961.1.2.10.12 UpdateRuleAction......................................................................... 1991.1.2.11 消息通信............................................................................................. 2011.1.2.11.1 Pub..................................................................................................2011.1.2.11.2 PubBroadcast................................................................................. 2031.1.2.11.3 RRpc............................................................................................... 2041.1.2.12 设备影子............................................................................................. 2061.1.2.12.1 GetDeviceShadow........................................................................... 2061.1.2.12.2 UpdateDeviceShadow.....................................................................207

1.2 设备端开发指南....................................................................................................2091.2.1 C SDK..................................................................................................... 2091.2.1.1 SDK获取............................................................................................... 2091.2.1.2 快速体验...............................................................................................2141.2.1.3 版本变动记录........................................................................................ 2281.2.1.4 常见问题列表........................................................................................ 2341.2.1.5 移植指南...............................................................................................2491.2.1.5.1 移植概述............................................................................................ 2501.2.1.5.2 SDK的同步与异步通信模式.................................................................. 2521.2.1.5.3 基于Make的编译说明..........................................................................2551.2.1.5.4 基于Make的交叉编译示例................................................................... 2611.2.1.5.5 基于代码抽取时的移植说明..................................................................2671.2.1.5.6 MCU上集成SDK..................................................................................2731.2.1.5.6.1 MCU+支持TCP的模组........................................................................2741.2.1.5.6.2 MCU+支持MQTT的模组.................................................................... 2951.2.1.5.6.3 CY8C4147AZI-S475移植示例........................................................... 3111.2.1.5.6.4 STM32F103+SIM800C移植示例........................................................ 3161.2.1.5.7 模组上集成SDK.................................................................................. 3321.2.1.5.7.1 在支持TCP的广域网模组上集成SDK.................................................... 3331.2.1.5.7.2 在支持MQTT的模组上集成SDK.......................................................... 3471.2.1.5.7.3 庆科MK3060/MK3080......................................................................359

IV 文档版本:20200417

Page 7: 阿里云IoT Link Rack 一体机

开发指南 /  目录

1.2.1.5.7.4 乐鑫ESP8266...................................................................................3601.2.1.5.7.5 MTK2503/MTK6261 + Nucleus 移植示例.......................................... 3611.2.1.5.8 高级系统集成SDK............................................................................... 3721.2.1.5.8.1 目标系统为64位Linux.......................................................................3721.2.1.5.8.2 目标系统为32位Linux...................................................................... 3731.2.1.5.8.3 目标系统为arm-linux...................................................................... 3771.2.1.5.8.4 在Windows下编译SDK.................................................................... 3781.2.1.5.9 windows...........................................................................................3781.2.1.5.9.1 安装Eclipse开发环境........................................................................ 3791.2.1.5.9.2 使用MQTT Topic与物联网平台通信....................................................3881.2.1.5.9.3 物模型编程接入LP-无TLS加密........................................................... 4041.2.1.5.9.4 以太网灯接入飞燕示例..................................................................... 4181.2.1.6 设备认证...............................................................................................4421.2.1.7 设备签名...............................................................................................4461.2.1.8 自定义MQTT Topic通信......................................................................... 4491.2.1.9 物模型编程........................................................................................... 4521.2.1.10 设备影子............................................................................................. 4571.2.1.11 远程配置............................................................................................. 4591.2.1.12 标签....................................................................................................4611.2.1.13 设备OTA开发....................................................................................... 4621.2.1.14 子设备管理..........................................................................................4691.2.1.15 WiFi配网............................................................................................. 4761.2.1.15.1 WiFi配网概述.................................................................................... 4761.2.1.15.2 一键配网.......................................................................................... 4801.2.1.15.3 手机热点配网....................................................................................4851.2.1.15.4 设备热点配网....................................................................................4901.2.1.15.5 零配.................................................................................................4951.2.1.16 设备reset............................................................................................ 5001.2.1.17 文件上传............................................................................................. 5021.2.1.18 HAL列表............................................................................................. 5101.2.1.18.1 基础HAL........................................................................................... 5101.2.1.18.2 MQTT连云HAL.................................................................................. 5271.2.1.18.3 线程HAL...........................................................................................5321.2.1.18.4 OTA HAL..........................................................................................5381.2.1.18.5 WiFi配网HAL.................................................................................... 5391.2.1.18.6 本地通信HAL.................................................................................... 5561.2.1.18.7 CoAP连云HAL.................................................................................. 5611.2.2 Android SDK.......................................................................................... 5681.2.2.1 工程配置...............................................................................................5681.2.2.2 认证与连接...........................................................................................5691.2.2.3 物模型开发...........................................................................................5731.2.2.4 自定义MQTT Topic通信......................................................................... 5771.2.2.5 远程配置.............................................................................................. 5801.2.2.6 设备OTA开发........................................................................................ 5811.2.2.7 标签.....................................................................................................582

文档版本:20200417 V

Page 8: 阿里云IoT Link Rack 一体机

开发指南 /  目录

1.2.2.8 子设备管理...........................................................................................5831.2.2.9 设备影子.............................................................................................. 5931.2.2.10 HTTP2 流通道..................................................................................... 5951.2.2.11 设备reset........................................................................................... 5981.2.2.12 错误码................................................................................................5991.2.2.13 常见问题.............................................................................................601

2 物联网边缘计算......................................................................6032.1 边缘端开发指南.................................................................................................... 603

2.1.1 设备接入SDK............................................................................................6032.1.1.1 C版本SDK..............................................................................................6032.1.1.2 Nodejs版本SDK.................................................................................... 6102.1.1.3 Python版本SDK.................................................................................... 6202.1.2 函数计算SDK........................................................................................... 6262.1.2.1 简介......................................................................................................6262.1.2.2 Nodejs.................................................................................................6272.1.2.2.1 Publish..............................................................................................6272.1.2.2.2 getThingProperties...........................................................................6282.1.2.2.3 setThingProperties........................................................................... 6292.1.2.2.4 callThingService............................................................................... 6312.1.2.2.5 getThingsWithTags........................................................................... 6322.1.2.2.6 invokeFunction................................................................................. 6332.1.2.3 Python.................................................................................................6352.1.2.3.1 publish............................................................................................. 6352.1.2.3.2 getThingProperties...........................................................................6362.1.2.3.3 setThingProperties........................................................................... 6372.1.2.3.4 callThingService............................................................................... 6382.1.2.3.5 getThingsWithTags........................................................................... 6392.1.2.3.6 invokeFunction................................................................................. 6402.1.3 边缘端HTTP API.......................................................................................6422.1.3.1 概述......................................................................................................6422.1.3.2 状态码..................................................................................................6432.1.3.3 身份认证...............................................................................................6442.1.3.3.1 CreateAuthCookie............................................................................. 6442.1.3.3.2 DeleteAuthCookie.............................................................................6452.1.3.4 设备管理...............................................................................................6462.1.3.4.1 GetThingProperties........................................................................... 6462.1.3.4.2 SetThingProperties........................................................................... 6472.1.3.4.3 CallThingServices............................................................................. 6492.1.3.4.4 BulkActions...................................................................................... 650

3 物联网设备身份认证................................................................6573.1 我是设备厂商....................................................................................................... 657

3.1.1 设备厂商对接流程..................................................................................... 6573.1.2 确定方案................................................................................................. 6583.1.3 对接准备工作........................................................................................... 659

VI 文档版本:20200417

Page 9: 阿里云IoT Link Rack 一体机

开发指南 /  目录

3.1.3.1 获取ProductKey....................................................................................6593.1.3.1.1 通过ID²控制台获取PK.......................................................................... 6593.1.3.1.2 通过阿里云物联网平台获取PK.............................................................. 6603.1.4 服务端对接.............................................................................................. 6603.1.5 设备端适配.............................................................................................. 6603.1.5.1 设备端适配:ID²-SE在三方OS上适配....................................................... 6613.1.5.2 设备端适配:ID²-SE在AliOS Things上适配..............................................6643.1.5.3 设备端适配:ID²-KM在Link Kit SDK上适配..............................................6663.1.5.4 设备端适配:ID²在Link TEE上适配..........................................................6763.1.6 自主验证................................................................................................. 680

3.2 我是芯片/模组厂商...............................................................................................6823.2.1 芯片/模组厂商 对接流程........................................................................... 6823.2.2 设备端对接..............................................................................................6833.2.2.1 模组厂商 对接ID².................................................................................. 6833.2.2.1.1 使用AliOS Things对接ID²-KM..............................................................6833.2.2.1.2 使用其他OS对接ID²-KM...................................................................... 6843.2.2.2 芯片厂商 对接ID²..................................................................................6863.2.2.2.1 使用AliOS Things 对接ID²-SE............................................................. 6863.2.2.2.2 其他OS对接ID²-SE............................................................................. 6883.2.3 烧录ID²................................................................................................... 6903.2.3.1 烧录ID²到模组.......................................................................................6903.2.3.2 烧录ID²到芯片...................................................................................... 6943.2.4 自主验证................................................................................................. 6973.2.5 产线审核................................................................................................. 698

3.3 API参考...............................................................................................................7013.3.1 设备端API手册......................................................................................... 7013.3.2 服务端API手册.........................................................................................7073.3.3 IROT硬件抽象层接口................................................................................ 7123.3.4 设备端SDK 适配手册................................................................................7203.3.5 错误码.................................................................................................... 7283.3.5.1 设备端错误代码.....................................................................................7283.3.5.2 iTLS错误码........................................................................................... 7293.3.5.3 服务端错误代码.................................................................................... 730

4 物联网络管理平台...................................................................7324.1 云端开发指南....................................................................................................... 732

4.1.1 云端API参考.............................................................................................7324.1.1.1 API列表.................................................................................................7324.1.1.2 概述......................................................................................................7344.1.1.3 公共参数............................................................................................... 7354.1.1.4 调用API................................................................................................ 7374.1.1.5 错误码.................................................................................................. 7384.1.1.6 基础管理............................................................................................... 7414.1.1.6.1 ListActivatedFeatures........................................................................ 7424.1.1.6.2 GetFreqBandPlanGroup.................................................................... 7454.1.1.6.3 GetUserLicense................................................................................. 747

文档版本:20200417 VII

Page 10: 阿里云IoT Link Rack 一体机

开发指南 /  目录

4.1.1.6.4 ListFreqBandPlanGroups...................................................................7534.1.1.7 网关管理............................................................................................... 7554.1.1.7.1 CountGateways..................................................................................7554.1.1.7.2 CreateGateway.................................................................................. 7574.1.1.7.3 DeleteGateway.................................................................................. 7604.1.1.7.4 GetGateway.......................................................................................7614.1.1.7.5 ListGateways..................................................................................... 7654.1.1.7.6 UpdateGateway.................................................................................7704.1.1.7.7 UpdateGatewayEnablingState...........................................................7724.1.1.8 网络管理............................................................................................... 7734.1.1.8.1 AcceptJoinPermissionAuthOrder........................................................7734.1.1.8.2 UpdateOwnedLocalJoinPermission................................................... 7754.1.1.8.3 SubmitJoinPermissionAuthOrder.......................................................7774.1.1.8.4 ReturnJoinPermission........................................................................7794.1.1.8.5 RejectJoinPermissionAuthOrder........................................................ 7804.1.1.8.6 ListRentedJoinPermissions................................................................ 7824.1.1.8.7 ListOwnedJoinPermissions................................................................ 7864.1.1.8.8 GetRentedJoinPermission..................................................................7904.1.1.8.9 GetOwnedJoinPermission..................................................................7924.1.1.8.10 GetJoinPermissionAuthOrder........................................................... 7964.1.1.8.11 DeleteLocalJoinPermission.............................................................. 7984.1.1.8.12 CreateLocalJoinPermission.............................................................. 8004.1.1.8.13 CountRentedJoinPermissions...........................................................8024.1.1.8.14 CountOwnedJoinPermissions...........................................................8034.1.1.8.15 CancelJoinPermissionAuthOrder......................................................8054.1.1.8.16 UpdateOwnedLocalJoinPermissionEnablingState............................8064.1.1.9 节点管理............................................................................................... 8084.1.1.9.1 AddNodeToGroup..............................................................................8084.1.1.9.2 UpdateDataDispatchEnablingState...................................................8104.1.1.9.3 UpdateDataDispatchConfig...............................................................8114.1.1.9.4 UnbindJoinPermissionFromNodeGroup.............................................8134.1.1.9.5 RemoveNodeFromGroup...................................................................8154.1.1.9.6 ListNodesByOwnedJoinPermissionId.................................................8164.1.1.9.7 ListNodesByNodeGroupId................................................................. 8194.1.1.9.8 ListNodeGroups................................................................................ 8234.1.1.9.9 GetNodeGroup.................................................................................. 8304.1.1.9.10 GetNode.......................................................................................... 8354.1.1.9.11 DeleteNodeGroup............................................................................8374.1.1.9.12 CreateNodeGroup............................................................................8394.1.1.9.13 CountNodesByOwnedJoinPermissionId............................................8404.1.1.9.14 CountNodesByNodeGroupId............................................................8424.1.1.9.15 CountNodeGroups........................................................................... 8434.1.1.9.16 BindJoinPermissionToNodeGroup.................................................... 8444.1.1.9.17 UpdateNodeGroup.......................................................................... 8464.1.1.10 上下行数据.......................................................................................... 848

VIII 文档版本:20200417

Page 11: 阿里云IoT Link Rack 一体机

开发指南 /  目录

4.1.1.10.1 SendUnicastCommand.................................................................... 8484.1.1.11 密钥管理..............................................................................................8494.1.1.11.1 CountGatewayTupleOrders...............................................................8504.1.1.11.2 CountNodeTupleOrders................................................................... 8524.1.1.11.3 GetGatewayTupleOrder....................................................................8544.1.1.11.4 GetGatewayTuplesDownloadUrl...................................................... 8564.1.1.11.5 GetNodeTupleOrder.........................................................................8584.1.1.11.6 GetNodeTuplesDownloadUrl........................................................... 8614.1.1.11.7 ListGatewayTupleOrders.................................................................. 8634.1.1.11.8 ListNodeTupleOrders....................................................................... 8674.1.1.11.9 SubmitNodeTupleOrder................................................................... 8714.1.1.11.10 SubmitGatewayTupleOrder............................................................ 8734.1.2 云端SDK参考........................................................................................... 8744.1.2.1 Java SDK使用说明................................................................................. 874

4.2 设备端开发指南....................................................................................................8764.2.1 获取网关SDK........................................................................................... 8764.2.2 获取节点SDK...........................................................................................878

5 物联网安全运营中心................................................................8835.1 设备接入..............................................................................................................8835.2 设备保护服务SDK.................................................................................................884

5.2.1 概览........................................................................................................ 8855.2.2 Linux系统集成.........................................................................................8855.2.3 Android系统集成.................................................................................... 8915.2.4 服务配置................................................................................................. 8935.2.5 客户端API............................................................................................... 894

5.3 设备取证服务SDK.................................................................................................8985.3.1 概览........................................................................................................ 8985.3.2 应用集成................................................................................................. 8995.3.3 平台、设备与服务适配..............................................................................9015.3.4 服务扩展................................................................................................. 902

文档版本:20200417 IX

Page 12: 阿里云IoT Link Rack 一体机

开发指南 /  目录

X 文档版本:20200417

Page 13: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1 物联网平台

1.1 云端开发指南

1.1.1 云端SDK参考

1.1.1.1 下载云端SDK物联网平台云端SDK用于调用云端API,以实现物联网平台的云端能力,如产品管理、设备管

理、Topic管理、数据流转规则管理、消息通信等。

说明:

本章节仅介绍云端SDK的使用。设备端SDK开发,请参见设备端SDK。

云端SDK下载地址

物联网平台提供的云端SDK语言版本有:Java、Python、PHP和.NET。

单击以下链接,进入相应的云端SDK源码下载地址。

• IoT Java SDK

• IoT Python SDK

• IoT PHP SDK

• IoT .NET SDK

下载云端SDK Demo

阿里云物联网平台提供云端SDK使用Demo。Demo中包含Java、Python、PHP、.NET版本SDK。

单击这里下载云端SDK Demo。

SDK使用说明

云端SDK使用帮助说明,请参见以下链接文档。

• Java SDK使用说明

• Python SDK使用说明

• PHP SDK使用说明

• .NET SDK使用说明

文档版本:20200417 1

Page 14: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.1.1.2 Java SDK使用说明物联网平台的Java SDK让开发人员可以方便地使用Java程序操作物联网平台。开发者可以使

用Maven依赖添加SDK,也可以下载安装包到本地直接安装。

安装SDK

1. 安装Java开发环境。

您可以从 Java 官方网站 下载,并按说明安装Java开发环境。

2. 安装IoT Java SDK。

a) 访问 Apache Maven 官网下载Maven软件。

b) 添加Maven项目依赖。

• 最新版 IoT Java SDK的Maven依赖坐标:

<!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-iot --><dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-iot</artifactId> <version>7.1.0</version></dependency>

• 阿里云Java SDK公共包Maven依赖坐标:

<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>3.5.1</version></dependency>

初始化SDK

说明:

以下示例以华东2地域及其服务接入地址为例。您在设置时,需使用您的物联网平台地域和对应的服

务接入地址。

String accessKey = "<your accessKey>";String accessSecret = "<your accessSecret>";DefaultProfile.addEndpoint("cn-shanghai", "cn-shanghai", "Iot", "iot.cn-shanghai.aliyuncs.com");IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKey, accessSecret);DefaultAcsClient client = new DefaultAcsClient(profile); //初始化SDK客户端

accessKey即您的账号的AccessKeyId, accessSecret即AccessKeyId对应的AccessKeySecret。

您可在中创建或查看您的AccessKey。

发起调用

物联网平台云端API,请参见API列表。

2 文档版本:20200417

Page 15: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

以调用Pub接口发布消息到Topic为例。

PubRequest request = new PubRequest(); request.setProductKey("productKey"); request.setMessageContent(Base64.encodeBase64String("hello world".getBytes())); request.setTopicFullName("/productKey/deviceName/get"); request.setQos(0); //目前支持QoS0和QoS1 try { PubResponse response = client.getAcsResponse(request); System.out.println(response.getSuccess()); System.out.println(response.getErrorMessage());} catch (ServerException e) { e.printStackTrace();} catch (ClientException e){ e.printStackTrace();}

1.1.1.3 Python SDK使用说明物联网平台提供Python语言的云端SDK供开发人员使用。本文介绍云端Python SDK的安装和配

置,及使用Python SDK调用云端API的示例。

安装SDK

1. 安装Python开发环境。

访问Python官网下载Python安装包,并完成安装。目前,支持2.6.5及以上版本。

2. 安装Python的包管理工具pip。(如果您已安装pip,请忽略此步骤。)

访问 pip 官网下载pip安装包,并完成安装。

3. 安装IoT Python SDK。

以管理员权限执以下命令,安装IoT Python SDK。请参见最新版aliyun-python-sdk-iot信息。

sudo pip install aliyun-python-sdk-coresudo pip install aliyun-python-sdk-iot

4. 将IoT Python SDK相关文件引入Python文件。

from aliyunsdkcore import clientfrom aliyunsdkiot.request.v20180120 import RegisterDeviceRequestfrom aliyunsdkiot.request.v20180120 import PubRequest...

初始化SDK

accessKeyId = '<your accessKey>' accessKeySecret = '<your accessSecret>'

文档版本:20200417 3

Page 16: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

clt = client.AcsClient(accessKeyId, accessKeySecret, 'cn-shanghai')

accessKeyId即您的账号的AccessKeyId, accessKeySecret即AccessKeyId对应

的AccessKeySecret。您可在中创建或查看您的AccessKey。

发起调用

物联网平台云端API,请参见#unique_13。

以调用Pub接口发布消息到设备为例。

request = PubRequest.PubRequest()request.set_accept_format('json') #设置返回数据格式,默认为XML,此例中设置为JSONrequest.set_ProductKey('productKey')request.set_TopicFullName('/productKey/deviceName/get') #消息发送到的Topic全名request.set_MessageContent('aGVsbG8gd29ybGQ=') #hello world Base64 Stringrequest.set_Qos(0)result = clt.do_action_with_exception(request)print 'result : ' + result

附录:Demo

下载云端SDK Demo。Demo中包含Java、Python、PHP、.NET和Go版本SDK示例。

另外,阿里云提供API在线调试工具 OpenAPI Explorer。在OpenAPI Explorer页,您可以快速检索

和试验调用API。系统会根据您输入的参数同步生成各语言SDK的Demo代码。各语言SDK Demo显

示在页面右侧示例代码页签下。在调试结果页签下,查看API调用的真实请求URL和JSON格式的返回

结果。

1.1.1.4 PHP SDK使用说明物联网平台提供PHP语言的云端SDK供开发人员使用。本文介绍云端PHP SDK的安装和配置,及使

用PHP SDK调用云端API的示例。

安装PHP SDK

IoT PHP SDK是Alibaba Cloud SDK for PHP的一部分。如果您已安装Alibaba Cloud SDK for

PHP,则无需再安装IoT PHP SDK。

1. 安装PHP开发环境。

需安装PHP 5.5.0或更高版本。访问PHP官网下载PHP安装包,并完成安装。

4 文档版本:20200417

Page 17: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. 安装Composer。

目前,通过Composer管理IoT PHP SDK,因此需在系统中安装Composer。

• Windows系统用户,请访问getcomposer.org,下载、安装Composer-Setup.exe。

• 使用cURL命令安装Composer。

curl -sS https://getcomposer.org/installer | php

说明:

如果由于网络问题无法安装,可以使用阿里云Composer全量镜像

3. 添加以下依赖,安装IoT PHP SDK。

composer require alibabacloud/iot

PHP SDK详情和使用指导,请参见openapi-sdk-php-iot和Alibaba Cloud SDK for PHP。

初始化SDK

初始化SDK示例代码如下:

<?phpinclude_once 'aliyun-php-sdk-core/Config.php';use \Iot\Request\V20180120 as Iot;//设置您的AccessKeyId/AccessSecret/ProductKey$accessKeyId = "";$accessSecret = "";$iClientProfile = DefaultProfile::getProfile("cn-shanghai", $accessKeyId, $accessSecret);$client = new DefaultAcsClient($iClientProfile);

accessKeyId即您的账号的AccessKeyId, accessSecret即AccessKeyId对应

的AccessKeySecret。您可在中创建或查看您的AccessKey。

发起调用

物联网平台云端API,请参见#unique_13。

以调用Pub接口发布数据到设备为例。

$request = new Iot\PubRequest();$request->setProductKey("productKey");$request->setMessageContent("aGVsbG93b3JsZA="); //hello world Base64 String.$request->setTopicFullName("/productKey/deviceName/get"); //消息发送到的Topic全名.$response = $client->getAcsResponse($request);print_r($response);

附录:Demo

下载云端SDK Demo。Demo中包含Java、Python、PHP、.NET和Go版本SDK示例。

文档版本:20200417 5

Page 18: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

另外,阿里云提供API在线调试工具 OpenAPI Explorer。在OpenAPI Explorer页,您可以快速检索

和试验调用API。系统会根据您输入的参数同步生成各语言SDK的Demo代码。各语言SDK Demo显

示在页面右侧示例代码页签下。在调试结果页签下,查看API调用的真实请求URL和JSON格式的返回

结果。

1.1.1.5 .NET SDK使用说明物联网平台提供.NET语言的云端SDK供开发人员使用。本文介绍云端.NET SDK的安装和配置,及使

用.NET SDK调用云端API的示例。

安装SDK

1. 安装.NET开发环境。

阿里云.NET SDK支持的开发环境如下:

• .NET Framework 4.0及以上版本。

• .NET Standard 2.0及以上版本。

• C# 4.0及以上版本。

• Visual Studio 2010 及以上版本。

2. 通过NuGet程序包管理器安装SDK。

以使用Visual Studio为例。

a) 在Visual Studio的解决方案资源管理器中,右键单击您的项目后,在菜单中选择管理NuGet程

序包。

b) 在NuGet 管理面板中,单击浏览。

c) 在选项卡中,输入aliyun-net-sdk,然后在列表中选择Authors为Alibaba Cloud的aliyun-

net-sdk-iot。

d) 单击安装。

初始化SDK

说明:

以下示例以华东2地域及其服务接入地址为例。您在设置时,需使用您的物联网平台地域和对应的服

务接入地址。

using Aliyun.Acs.Core;using Aliyun.Acs.Core.Exceptions;using Aliyun.Acs.Core.Profile;DefaultProfile.AddEndpoint("cn-shanghai", "cn-shanghai", "Iot", "iot.cn-shanghai.aliyuncs.com");IClientProfile clientProfile = DefaultProfile.GetProfile("cn-shanghai", "<your-access-key-id>", "<your-access-key-secret>");

6 文档版本:20200417

Page 19: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

DefaultAcsClient client = new DefaultAcsClient(clientProfile);

请在中创建或查看您的AccessKeyId和AccessKeySecret。

发起调用

物联网平台云端API,请参见#unique_13。

以调用Pub接口向Topic发布消息为例。

PubRequest request = new PubRequest();request.ProductKey = "<productKey>";request.TopicFullName = "/<productKey>/<deviceName>/get";byte[] payload = Encoding.Default.GetBytes("Hello World.");String payloadStr = Convert.ToBase64String(payload);request.MessageContent = payloadStr;request.Qos = 0;try{ PubResponse response = client.GetAcsResponse(request); Console.WriteLine("publish message result: " + response.Success); Console.WriteLine(response.ErrorMessage);}catch (ServerException e){ Console.WriteLine(e.ErrorCode); Console.WriteLine(e.ErrorMessage);}catch (ClientException e){ Console.WriteLine(e.ErrorCode); Console.WriteLine(e.ErrorMessage);}

附录:Demo

下载云端SDK Demo。Demo中包含Java、Python、PHP、.NET和Go版本SDK示例。

另外,阿里云提供API在线调试工具 OpenAPI Explorer。在OpenAPI Explorer页,您可以快速检索

和试验调用API。系统会根据您输入的参数同步生成各语言SDK的Demo代码。各语言SDK Demo显

示在页面右侧示例代码页签下。在调试结果页签下,查看API调用的真实请求URL和JSON格式的返回

结果。

1.1.2 云端API参考

1.1.2.1 API列表以下是物联网平台 API 列表。

产品管理相关 API

API 描述

CreateProduct 创建产品。

文档版本:20200417 7

Page 20: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API 描述

UpdateProduct 修改产品信息。

QueryProductList 查询产品列表。

QueryProduct 查询产品详细信息。

DeleteProduct 删除指定产品。

CreateProductTags 创建产品标签。

UpdateProductTags 更新产品标签。

DeleteProductTags 删除产品标签。

ListProductTags 查询产品的所有标签。

ListProductByTags 根据标签查询产品。

设备管理相关 API

API 描述

RegisterDevice 注册设备。

QueryDeviceDetail 查询设备详情。

BatchQueryDeviceDetail 批量查询设备详情。

QueryDevice 查询产品的设备列表。

DeleteDevice 删除设备。

GetDeviceStatus 获取设备的运行状态。

BatchGetDeviceState 批量获取设备状态。

DisableThing 禁用设备。

EnableThing 解禁设备。

BatchCheckDeviceNames 批量检查设备名称。

BatchRegisterDeviceWithApplyId 根据 ApplyId 批量申请设备。

BatchRegisterDevice 批次申请特定数量设备。

QueryBatchRegisterDeviceStatus 查询批量注册设备状态。

QueryPageByApplyId 查询批次设备列表。

QueryDeviceEventData 查询设备的事件历史数据。

QueryDevicePropertyData 查询设备的属性历史数据。

QueryDevicePropertiesData 批量查询指定设备的多个属性的历史数据。

QueryDeviceServiceData 获取设备的服务记录历史数据。

8 文档版本:20200417

Page 21: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API 描述

InvokeThingService 调用设备的服务。

InvokeThingsService 批量调用设备的服务。

QueryDevicePropertyStatus 查询设备的属性快照。

SetDeviceProperty 设置设备的属性。

SetDevicesProperty 批量设置设备属性。

SaveDeviceProp 设置设备标签。

QueryDeviceProp 查询设备标签列表。

DeleteDeviceProp 删除设备标签。

GetThingTopo 查询网关设备或子设备所具有的拓扑关系。

NotifyAddThingTopo 通知网关增加设备拓扑关系。

RemoveThingTopo 移除网关设备或子设备所具有的拓扑关系。

QueryDeviceStatistics 获取设备的统计数量。

GetGatewayBySubDevice 根据挂载的子设备信息查询对应的网关设备信息。

QueryDeviceByTags 根据标签查询设备。

SetDeviceDesiredProperty 为指定设备批量设置期望属性值。

QueryDeviceDesiredProperty 查询指定设备的期望属性值。

QueryDeviceFileList 查询指定设备上传到物联网平台的所有文件。

QueryDeviceFile 查询指定设备上传到物联网平台的指定文件信息。

DeleteDeviceFile 删除指定设备上传到物联网平台的指定文件。

BatchUpdateDeviceNickname 批量更新设备备注名称。

分组管理相关API

API 描述

CreateDeviceGroup 创建分组。

DeleteDeviceGroup 删除分组。

UpdateDeviceGroup 修改分组信息。

QueryDeviceGroupInfo 查询分组详情。

QueryDeviceGroupList 分页查询分组列表。

BatchAddDeviceGroupRelations 添加设备到分组。

文档版本:20200417 9

Page 22: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API 描述

BatchDeleteDeviceGroupRelations 删除分组中已添加的指定设备。

SetDeviceGroupTags 添加或更新分组标签。

QueryDeviceGroupTagList 查询分组标签列表。

QueryDeviceGroupByDevice 查询指定设备所在的分组列表。

QuerySuperDeviceGroup 根据子分组ID查询父分组信息。

QueryDeviceListByDeviceGroup 查询分组中的设备列表。

QueryDeviceGroupByTags 根据标签查询设备分组。

规则引擎相关 API

API 描述

ListRule 查询规则列表。

CreateRule 创建规则。

GetRule 查询规则信息。

UpdateRule 修改规则。

DeleteRule 删除规则。

ListRuleActions 查询规则动作列表。

GetRuleAction 查询规则动作信息。

CreateRuleAction 创建规则动作。

UpdateRuleAction 更新规则动作。

DeleteRuleAction 删除规则动作。

StartRule 启动规则。

StopRule 停止规则。

Topic 管理相关 API

API 描述

QueryProductTopic 查询产品Topic类。

CreateProductTopic 创建产品Topic类。

UpdateProductTopic 修改产品Topic类。

DeleteProductTopic 删除产品Topic类。

CreateTopicRouteTable 添加Topic路由表。

10 文档版本:20200417

Page 23: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API 描述

QueryTopicRouteTable 查询Topic路由表。

QueryTopicReverseRouteTable 查询Topic反向路由表。

DeleteTopicRouteTable 删除Topic路由表。

消息通信相关 API

API 描述

Pub 发布消息到Topic。

RRpc 发消息给设备,并同步返回响应。

PubBroadcast 发布广播消息。

设备影子相关 API

API 描述

GetDeviceShadow 查询设备影子。

UpdateDeviceShadow 更新设备影子。

1.1.2.2 概述物联网平台提供云端管理产品、设备、分组、Topic、规则、设备影子等API接口,和从云端发布消息

的API接口。使用云端SDK,向API的服务端地址发送HTTPS/HTTP GET或POST请求,并按照API接口

说明,在请求中加入相应请求参数来调用API。物联网平台根据请求的处理情况,返回处理结果。

调用API的方法和说明,请参见以下链接文档。

• 调用API

• 公共参数

• #unique_104

文档版本:20200417 11

Page 24: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.1.2.3 调用API本文档主要介绍调用物联网平台云端API的请求结构和请求示例。

请求结构

请求结构如下:

http://Endpoint/?Action=xx&Parameters

参数 说明

Action 要执行的操作,即云端API接口的名称。例如,调用Pub接口向指定Topic发布消息,Action对应的值就是Pub,即Action=Pub。

Parameters 请求参数。每个参数之间用(&)符号分隔。

请求参数由公共请求参数和API自定义参数组成。公共参数中包含API版本号、

身份验证等信息。

下面以调用Pub接口向指定Topic发布消息为例:

说明:

本文档示例均使用华东2(上海)地域的接入地址。为了便于阅读,本文档中的示例均做了格式化处

理。

API在线调试

阿里云提供API在线调试工具 OpenAPI Explorer。在OpenAPI Explorer页,您可以快速检索和试验

调用API。系统会根据您输入的参数同步生成各语言SDK的Demo代码。各语言SDK Demo显示在页

面右侧示例代码页签下供您参考。在调试结果页签下,查看API调用的真实请求URL和JSON格式的返

回结果。

12 文档版本:20200417

Page 25: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.1.2.4 公共参数本文档介绍物联网平台云端API的公共请求参数和公共返回参数。

公共请求参数

公共请求参数是调用每个API时都需要使用的请求参数。

名称 类型 是否必需 描述

Format String 否 返回值的类型,支持JSON和XML类型。默认为XML。

Version String 是 API版本号,为日期形式:YYYY-MM-DD,最新版本为2018-01-20 。每个接口可以存在多个版本。

Signature String 是 签名结果串。

SignatureMethod String 是 签名方式,目前支持HMAC-SHA1。

Timestamp String 是 请求的时间戳。日期格式按照ISO8601标准表示,并需要使用UTC时间。格式为YYYY-MM-DDThh:mm:ssZ。

例如,2016-01-04T12:00:00Z表示北

京时间2016年01月04日20点0分0秒。

SignatureVersion String 是 签名算法版本。目前版本是1.0。

SignatureNonce String 是 唯一随机数。用于防止网络重放攻击。用户在不同请求中要使用不同的随机数值。

示例

https://应用网关IP:port/data/api.json/?Format=XML&Version=2018-01-20&Signature=Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D&SignatureMethod=HMAC-SHA1&SignatureNonce=15215528852396&SignatureVersion=1.0&Timestamp=2018-05-20T12:00:00Z

公共返回参数

API返回结果采用统一格式,返回2xx HTTP状态码代表调用成功;返回4xx或5xx HTTP状态码代表调

用失败。调用成功返回的数据格式有XML和JSON两种。可以在发送请求时,指定返回的数据格式。

默认为XML格式。

每次接口调用,无论成功与否,系统都会返回一个唯一识别码RequestId。

文档版本:20200417 13

Page 26: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 调用成功的返回示例。

- XML格式

<?xml version="1.0" encoding="UTF-8"?> <!—结果的根结点--><接口名称+Response> <!—返回请求标签--> <RequestId>4C467B38-3910-447D-87BC-AC049166F216</RequestId> <!—返回结果数据--></接口名称+Response>

- JSON格式

{ "RequestId": "4C467B38-3910-447D-87BC-AC049166F216" /* 返回结果数据 */}

• 调用失败的返回示例。

调用接口出错后,将不会返回结果数据。可根据错误码来定位错误原因。

当调用出错时,HTTP请求返回一个4xx或5xx的HTTP状态码。返回的消息体中是具体的错误代

码及错误信息。另外,还包含一个全局唯一的请求ID(RequestId)。在您不能确认错误的情况

下,可以联系阿里云客服或提交工单,并提供RequestId值,以便工作人员尽快帮您解决问题。

- XML格式

<?xml version="1.0" encoding="UTF-8"?><Error> <RequestId>8906582E-6722-409A-A6C4-0E7863B733A5</RequestId> <Code>UnsupportedOperation</Code> <Message>The specified action is not supported.</Message></Error>

- JSON格式

{ "RequestId": "8906582E-6722-409A-A6C4-0E7863B733A5", "Code": "UnsupportedOperation", "Message": "The specified action is not supported."}

1.1.2.5 错误码本文档列举调用物联网平台API出错时,返回的错误信息。入参数据格式错误、超出限定值、入参缺

少必需参数等错误修改,请参见具体API文档的请求参数描述。

系统错误码

以iot.system开头的错误码为系统相关错误码。

14 文档版本:20200417

Page 27: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.system.SystemException 系统异常。

请稍后重试。

公共错误码

以iot.common开头的错误码为公共错误码。

错误码 描述

iot.common.InvalidPageParams 分页大小或者分页页号不合法。

请参见具体API文档的分页相关参数描述,如

PageSize。

iot.common.InvalidTenant 不合法的租户。

请确认阿里云账号信息和账号权限。

iot.common.QueryDeviceActionError 查询设备失败。

请确认入参信息正确,然后重试。

iot.common.QueryDevicePropertyActionError

查询设备属性失败。

请确认入参信息正确,然后重试。

iot.common.QueryProductActionError 查询产品失败。

请确认入参信息正确,然后重试。

iot.common.QueryProductCountActionError 查询产品总数失败。

请确认入参信息正确,然后重试。

产品(Product)相关错误码

以iot.prod开头的错误码为产品相关错误码。

错误码 描述

iot.prod.AlreadyExistedProductName 已经存在相同的产品名称。一个阿里云账号下的产品名称不能重复。

iot.prod.CreateProductFailed 创建产品失败。

请确认入参信息正确,然后重试。

文档版本:20200417 15

Page 28: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.prod.CreateProductTopicFailed 创建产品的Topic类失败。

请确认入参信息正确,然后重试。

iot.prod.InvalidAliyunCommodityCode 入参AliyunCommodityCode值错误。

AliyunCommodityCode的可选值只有

iothub_senior和iothub。

iot.prod.InvalidFormattedCatId 入参CategoryId(产品的设备类型)错误。

iot.prod.InvalidFormattedProductkey 入参产品ProductKey格式错误。

请核对输入的ProductKey值。

iot.prod.InvalidFormattedProductName 入参产品名称格式错误。

产品名应满足以下限制:由中文、英文字母、数

字和下划线(_)组成,长度为4-30位(一个中

文字符占两位)。

iot.prod.LongProductDesc 产品描述字符数超出限定值。

描述信息应在100字符以内。

iot.prod.InvalidNodeType 产品的节点类型错误。

节点类型支持的可选值:

• 0:设备

• 1:网关

iot.prod.NotExistedProduct 产品不存在。

输入的ProductKey值在当前账号下不存在。

iot.prod.NotSeniorProduct 产品不是高级版产品。

iot.prod.NullProductKey 入参产品ProductKey不能为空。

iot.prod.NullProductName 入参产品名称不能为空。

iot.prod.ProductCountExceedMax 产品总数已超过最大限制数量。

一个阿里云账号下最多可有1,000个产品。

iot.prod.QueryDeviceCountActionError 查询产品下的设备总数失败。

请确认入参信息正确,然后重试。

16 文档版本:20200417

Page 29: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.prod.QueryProductAbilitiesFailed 获取产品功能失败。

请确认入参信息是否正确,如Identifier值等。

iot.prod.QueryProductAbilityFailed 查询产品功能失败。

请确认入参信息是否正确,如Identifier值等。

iot.prod.QueryProductListActionError 获取产品列表数据失败。

请确认入参信息正确,然后重试。

iot.prod.UpdateProductFailed 更新产品信息失败。

请确认入参信息正确,然后重试。

设备(Device)相关错误码

以iot.device开头的错误码为设备相关错误码。

错误码 描述

iot.device.AddTopoRelationFailed 添加拓扑关系失败。

请确认入参信息正确,然后重试。

iot.device.AlreadyExistedDeviceName 设备名称已经存在。

设备名称需在产品维度唯一。

iot.device.ApplyManyDevicesFailed 申请批量创建设备失败。

请确认入参信息正确,然后重试。

iot.device.CreateDeviceFailed 创建设备失败。

请确认入参信息正确,然后重试。

iot.device.CreateDeviceTaskIsRunning 创建设备的申请任务还在执行中。

iot.device.DeviceApplyIsNotFound 申请设备的申请单不存在。

请确认输入的ApplyId值。其值需与您调

用BatchCheckDeviceNames返回的ApplyId值

一致。

iot.device.DeviceCountExceeded 批量申请的设备数量超过最大值。

单次调用,最多批量注册1,000 个设备。

文档版本:20200417 17

Page 30: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.device.DeleteDeviceFailed 删除设备失败。

请确认入参信息正确,然后重试。

iot.device.DeleteDevicePropertyFailed 删除设备属性失败。

请确认入参信息正确,然后重试。

iot.device.DisableDeviceFailed 禁用设备失败。

请确认入参信息正确,然后重试。

iot.device.EnableDeviceFailed 启用设备失败。

请确认入参信息正确,然后重试。

iot.device.InactiveDevice 设备未激活,即物理设备从未连接物联网平台。

iot.device.InvalidFormattedApplyId 创建设备的申请单(ApplyId)错误。

其值需与您调用BatchCheckDeviceNames返

回的ApplyId值一致。

iot.device.IncorrentDeviceApplyInfo 设备申请信息错误。

请确认入参信息,如ApplyId等。

iot.device.InvalidFormattedDeviceName 设备名称格式错误。

设备名称长度为4-32个字符,可以包含英文

字母、数字和特殊字符:连字符(-)、下划

线(_)、at符号(@)、点号(.)、和英文冒

号(:)。

iot.device.InvalidFormattedDevicePropertyKey

设备属性标识符格式错误。

请查看相关API文档中,关于入参属性格式的描

述。

iot.device.InvalidFormattedDevicePropertiesString

入参设备属性格式错误。

请查看相关API文档中,关于入参属性格式的描

述。

18 文档版本:20200417

Page 31: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.device.InvalidIoTId 设备ID错误。

请调用QueryDeviceDetail或QueryDevice查

看正确的IotId值,或用ProductKey与

DeviceName组合代替IotId。

iot.device.InvalidTimeBucket 指定的时间区间不合法。

请根据API文档中描述正确设置参数。

• Asc为0倒序查询时,StartTime必须大于EndTime。

• Asc为1正序查询时,StartTime必须小于EndTime。

iot.device.InvokeThingServiceFailed 调用设备服务失败。

请检查输入参数是否正确,如Args的参数格式和

取值等。

iot.device.LongDevicePropertiesString 入参设备属性长度超过最大值。

请查看相关API文档的限制说明。

iot.device.NoneDeviceNameElement 设备名称列表为空。

iot.device.NoneDeviceProperties 没有有效的设备属性。

请核对传入的属性Identifier是否与TSL中定义的

一致。

iot.device.NotExistedDevice 设备不存在。

传入的设备IotId、ProductKey

或DeviceName值错误。请调

用QuertDeviceDetail或QueryDevice查看正确

值。

iot.device.NullApplyId 创建设备的申请ID(ApplyId)不能为空。

iot.device.NullDeviceName 设备名称不能为空。

iot.device.NullDevicePropertyKey 设备属性名称不能为空。

iot.device.NullDevicePropertiesString 入参设备属性不能为空。

文档版本:20200417 19

Page 32: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.device.QueryDeviceApplyActionError 查询设备申请单信息出错。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceAttrDataHistoryFailed 获取设备属性数据历史记录失败。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceAttrStatusFailed 获取设备属性状态信息失败。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceEventHistoryFailed 获取设备事件调用记录失败。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceListActionError 查询设备列表失败。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceServiceHistoryFailed 获取设备服务调用记录失败。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceStatisticsFailed 查询设备统计信息失败。

请确认入参信息正确,然后重试。

iot.device.QueryDeviceStatusFailed 查询设备状态信息失败。

请确认入参信息正确,然后重试。

iot.device.QueryTopoRelationFailed 查询拓扑关系失败。

请确认入参信息是否正确。如,传入的

PageSize值大于限定值50会报此错误。

iot.device.RemoveTopoRelationFailed 移除拓扑关系失败。

请确认入参信息正确,然后重试。

iot.device.SaveOrUpdateDevicePropertiesFailed

新增或者修改设备属性失败。

请确认入参信息正确,然后重试。

iot.device.SetDevicePropertyFailed 设置设备属性失败。

请检查入参Items的参数值和格式是否正确,指

定的属性是否是读写型。

20 文档版本:20200417

Page 33: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.device.TooManyDevicePropertiesPerTime 传入的属性个数超过限定值。

请参见相关API文档限制说明。

iot.device.TopoRelationCountExceeded 拓扑关系数量过多。

请参见 《捂脸平台产品简介》 文档使用限制章

节中网关与子设备数量限制。

iot.device.VerifyDeviceFailed 验证设备失败。

请确认入参信息正确,然后重试。

设备分组(Group)相关错误码

以iot.group开头的错误码为设备分组相关错误码。

错误码 描述

iot.group.NullGroupId 入参分组ID没有赋值。

iot.group.DeleteGroupFailed 删除分组失败。

请确认入参信息正确,然后重试。

iot.group.SubGroupNotNull 分组下有子分组。

当分组下有子分组时,不能删除分组,需先删除

子分组。

iot.group.InvalidGroupName 分组名称不合法。

分组名称可包含中文汉字、英文字母、数字和下

划线(_)。长度范围 4 - 30 字符(一个中文汉

字占二个字符)。

iot.group.GroupNameExisted 分组名称已存在。

iot.group.QueryGroupInfoFailed 查询分组详情失败。

请确认入参信息正确,然后重试。

iot.group.NotExistedGroup 分组不存在。

请确认GroupId值。

iot.group.QueryGroupCountFailed 查询分组数量失败。

请确认入参信息正确,然后重试。

文档版本:20200417 21

Page 34: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.group.QueryGroupListFailed 查询分组列表失败。

请确认入参信息正确,然后重试。

iot.group.BindGroupRelationFailed 绑定分组关系失败。

请确认入参信息正确,然后重试。

iot.group.UpdateGroupFailed 修改分组信息失败。

请确认入参信息正确,然后重试。

iot.group.QueryGroupTreeFailed 获取分组关系结构失败。

请确认入参信息正确,然后重试。

iot.group.CreateGroupFailed 创建分组失败。

请确认入参信息正确,然后重试。

iot.group.InvalidFormattedTagString 标签格式不合法。

标签数据为JSON格式。由标

签的tagKey和tagValue组

成,tagKey和tagValue均不能为空。多个标

签以英文逗号间隔。如,[{"tagKey":"h1","

tagValue":"rr"},{"tagKey":"7h","tagValue":"rr

"}]。

iot.group.TagCountExceedMax 标签数量超过最大值。

每个分组最多可有100个标签。

iot.group.GroupCountExceedMax 分组数量超过最大值。

• 一个分组最多可包含100个子分组。• 一个设备最多可以被添加到10个分组中。

iot.group.SetGroupTagFailed 设置分组标签信息失败。

请确认入参信息正确,然后重试。

iot.group.QueryGroupTagFailed 查询分组标签信息失败。

请确认入参信息正确,然后重试。

22 文档版本:20200417

Page 35: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.group.LongGroupDescError 分组描述字段过长。

分组描述长度限制为100字符(一个中文汉字占

一个字符)。

iot.group.QueryGroupRelationFailed 查询分组关系失败。

请确认入参信息正确,然后重试。

iot.group.GroupLevelExceedingLimitError 分组层级超过限制。

分组只支持三级嵌套,即分组>子分组>子子分

组。

消息相关错误码

以iot.messagebroker开头的错误码为消息相关错误码。此类错误码主要出现在调用消息通信相

关API、设备影子相关API和规则引擎相关API失败时。(规则引擎相关API调用失败错误码,请见本

文档下一章节。)

错误码 描述

iot.messagebroker.CreateTopicRouteFailed 创建Topic之间消息路由失败。

请确认入参信息正确,然后重试。

iot.messagebroker.CreateTopicTemplateException

创建Topic类过程发生异常。

请确认入参信息正确,然后重试。

iot.messagebroker.CreateTopicTemplateFailed

创建Topic类失败。

请确认入参信息正确,然后重试。

iot.messagebroker.DeleteTopicTemplateException

删除Topic类过程发生异常。

请确认入参信息正确,然后重试。

iot.messagebroker.DeleteTopicTemplateFailed

删除Topic类失败。

请确认入参信息正确,然后重试。

iot.messagebroker.DestTopicNameArraySizeIsLarge

同一消息源Topic配置的路由目标Topic数量超过最大限制数。

一个源Topic最多可对应100个目标Topic。

文档版本:20200417 23

Page 36: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.messagebroker.DeleteTopicRouteFailed 删除指定Topic间的路由失败。

请确认入参信息正确,然后重试。

iot.messagebroker.DesireInfoInShadowMessageIsNotJson

设备影子中的desire信息不是JSON格式。

iot.messagebroker.DesireValueIsNullInShadowMessage

设备影子中的desire信息值为空。

iot.messagebroker.ElementKeyOrValueIsNullInDesire

desire信息包含有空的属性标识符或者属性值。

iot.messagebroker.ElementKeyOrValueIsNullInReport

report信息包含有空的属性标识符或者属性值。

iot.messagebroker.HALFCONN 由于设备为半连接状态导致失败。

iot.messagebroker.InvalidFormattedSrcTopicName

消息源Topic名称格式错误。

可在控制台设备详情页的Topic列表下查看设备

的Topic。

iot.messagebroker.InvalidFormattedTopicName

Topic格式错误。

可在控制台设备详情页的Topic列表下查看设备

的Topic。

iot.messagebroker.InvalidFormattedTopicTemplateId

Topic类ID格式错误。

可调用QueryProductTopic查看TopicId。

iot.messagebroker.InvalidTimeoutValue 超时时间参数设置有误。

请参见相关API文档查看时间设置方法。

iot.messagebroker.InvalidTopicTemplateOperationValue

Topic类的操作权限值错误。操作权限取值:

SUB:订阅。

PUB:发布。

ALL:发布和订阅。

iot.messagebroker.InvalidVersionValueInShadowMessage

设备影子中的version值错误。

iot.messagebroker.MethodValueIsNotUpdate

设备影子中的method信息值不是update。

24 文档版本:20200417

Page 37: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.messagebroker.MessageContentIsNotBase64Encode

消息内容没有经过base64编码。

iot.messagebroker.NoneElementInDesire desire信息中没有属性。

iot.messagebroker.NoneElementInReport report信息中没有属性。

iot.messagebroker.NoneElementDestTopicNameInArray

目标Topic列表中没有元素。

iot.messagebroker.NotFoundDesireInShadowMessage

设备影子的state信息中没有desire信息。

iot.messagebroker.NotFoundMethodInShadowMessage

设备影子没有method信息。

iot.messagebroker.NotFoundReportInShadowMessage

设备影子中没有report信息。

iot.messagebroker.NotFoundStateInShadowMessage

设备影子中没有state信息。

iot.messagebroker.NotFoundVersionOrNullVersionValue

缺少version信息或者version值为空。

iot.messagebroker.NotMatchedProductKeyWithSrcTopicOwner

消息源Topic对应的产品ID不属于当前用户。

iot.messagebroker.NullMessageContent 消息内容不能为空。

iot.messagebroker.NullShadowMessage 设备影子内容不能为空。

iot.messagebroker.NullSrcTopicName 消息源Topic名称不能为空。

iot.messagebroker.NullTopicName Topic不能为空。

iot.messagebroker.NullTopicTemplateId Topic类ID不能为空。

iot.messagebroker.NullTopicTemplateOperation

Topic类的操作权限不能为空。

iot.messagebroker.OFFLINE 由于设备离线导致失败。

iot.messagebroker.PublishMessageException

发送消息过程出现异常。

请确认入参信息正确,然后重试。

iot.messagebroker.PublishMessageFailed 发送消息失败。

请确认入参信息正确,然后重试。

iot.messagebroker.QueryDeviceShadowActionError

查询设备影子失败。

请确认入参信息正确,然后重试。

文档版本:20200417 25

Page 38: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.messagebroker.QueryProductTopicListActionError

获取Topic类列表失败。

请确认入参信息正确,然后重试。

iot.messageborker.QueryTopicReverseRouteTableListActionError

获取消息反向路由列表(即消息源Topic列表)失败。

请确认入参信息正确,然后重试。

iot.messageborker.QueryTopicRouteTableListActionError

获取消息路由列表失败。

请确认入参信息正确,然后重试。

iot.messagebroker.QueryTopicTemplateActionError

查询Topic类失败。

请确认入参信息正确,然后重试。

iot.messagebroker.QueryTopicTemplateException

获取Topic类过程发生异常。

请确认入参信息正确,然后重试。

iot.messagebroker.RateLimit 由于限流导致失败。

请参见 《物联网平台产品简介》 文档中使用限

制章节。

iot.messagebroker.ReportInShadowMessageIsNotJson

设备影子中的state信息中的report信息不是JSON格式。

iot.messagebroker.RrpcException RRPC发送消息过程出现异常。

请确认入参信息正确,然后重试。

iot.messagebroker.RrpcFailed RRPC发送消息失败。

请确认入参信息正确,然后重试。

iot.messagebroker.ShadowMessageIsNotJson

设备影子不是JSON格式。

iot.messagebroker.ShadowMessageLengthIsLarge

设备影子的长度超过最大限制。

设备影子文档的大小限制16 KB。

iot.messagebroker.TIMEOUT 由于超时导致失败。

iot.messagebroker.TooManyElementInDesire

desire信息中包含的属性总数超过最大限定数。

设备影子JSON文档的属性数量限制为128。

26 文档版本:20200417

Page 39: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.messagebroker.TooManyElementInReport

report信息包含的属性总数超过限定最大数。

设备影子JSON文档的属性数量限制为128。

iot.messagebroker.TopicAlreadyFound 同一产品下Topic类名称重复。

iot.messagebroker.TopicTemplateCountExceedMax

产品的Topic类数量超过最大值。

一个产品最多可以定义50个Topic类。

iot.messagebroker.TopicTemplateIsNotFound

Topic类不存在。

可调用QueryProductTopic查看产品

的Topic类。

iot.messagebroker.UpdateDeviceShadowMessageFailed

更新设备影子失败。

请确认入参信息正确,然后重试。

iot.messagebroker.UpdateTopicTemplateException

更新Topic类过程发生异常。

请确认入参信息正确,然后重试。

iot.messagebroker.UpdateTopicTemplateFailed

更新Topic类失败。

请确认入参信息正确,然后重试。

规则相关错误码

以iot.rule和iot.ruleng开头的错误码,及少量iot.messagebroker开头的错误码,是规则引擎相关错

误码。

提示出现异常或失败时,请确认入参信息正确,然后重试。

错误码 描述

iot.rule.CreateRuleException 创建规则过程发生异常。

请确认入参信息正确,然后重试。

iot.rule.DeleteRuleFailed 删除规则失败。

请确认入参信息正确,然后重试。

iot.rule.IncorrentRuleActionId 规则动作ID错误。

可调用ListRuleActions查看规则动作ID。

文档版本:20200417 27

Page 40: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.rule.IncorrentRuleActionType 规则动作类型。

规则动作类型参数Type支持可选值:

• REPUBLISH:另一个物联网平台Topic。

iot.rule.IncorrentRuleId 规则ID错误。

iot.rule.NullForwardDestForRule 转发数据目的地不能为空。

Configuration中的具体配置方法,请参

见CreateRuleAction。

iot.rule.NullSqlForRule 规则的SQL语句不能为空。

iot.rule.NotFoundRule 规则不存在。

请输入正确的规则ID (RuleId)。可调

用ListRule查看账号下所有规则的RuleId。

iot.rule.NotFoundRuleAction 规则动作不存在。

请输入正确的规则动作ID (ActionId)。可

调用ListRuleActions查看某个规则下的所

有ActionId。

iot.rule.ParseRuleActionConfigError 无法正常解析规则动作的配置。

请确认入参信息正确,然后重试。

iot.rule.QueryRuleActionListError 查询规则动作列表失败。

请确认入参信息正确,然后重试。

iot.rule.QueryRulePageActionError 分页获取规则列表失败。

请确认入参信息正确,然后重试。

iot.rule.RuleActionIsAlreadyCreated 已存在相同的规则动作。

iot.rule.RuleCountExceedMax 规则总数超过最大限制数。

单账号最多可以设置1000条规则。

iot.rule.RuleNameIsAlreadyExisted 规则名称已经存在。

iot.rule.StartRuleFailed 启动规则失败。

请确认入参信息正确,然后重试。

28 文档版本:20200417

Page 41: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.rule.StopRuleFailed 停止规则失败。

请确认入参信息正确,然后重试。

iot.rule.TooManyRuleAction 规则动作数量超过最大限制。

一条规则中转发数据的操作不能超过10个。

iot.rule.UpdateRuleFailed 更新规则失败。

请确认入参信息正确,然后重试。

iot.ruleng.CreateRuleActionFailed 创建规则动作失败。

请确认入参信息正确,然后重试。

iot.ruleng.DeleteRuleActionFailed 删除规则动作失败。

请确认入参信息正确,然后重试。

iot.ruleng.IncorrectType 应用规则的Topic类型错误。

TopicType支持的可选值:

• 0:系统Topic• 1:自定义Topic• 2:设备状态消息Topic

iot.ruleng.IncorrectSysTopic 错误的系统Topic。

可在控制台设备详情页的Topic列表页签下查看

正确的Topic。

iot.ruleng.QueryRuleActionFailed 获取规则动作失败。

请确认入参信息正确,然后重试。

iot.ruleng.RuleActionConfigurationIsNotJson 规则动作配置不是JSON格式。

参数Configuration的值必须是正确的JSON格

式。具体请参见CreateRuleAction。

iot.ruleng.RuleAlreadyIsStarted 规则是已启动状态。

iot.ruleng.NullRuleActionConfig 规则动作配置(参数Configuration)不能为空。

iot.ruleng.NullRuleActionType 规则动作类型(参数Type)不能为空。

文档版本:20200417 29

Page 42: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 描述

iot.messagebroker.IncorrectRuleSql 规则的SQL配置错误。

请根据CreateRule说明配置SQL。

iot.messagebroker.QueryRuleConfigActionException

获取规则配置信息过程出现异常。

请确认入参信息正确,然后重试。

以下表格分别列举消息转发目标设置失败的特有错误码。

表 1-1: 目标为REPUBLISH(另一个IoT Topic)的错误码

错误码 描述

iot.messagebroker.InvalidFormattedTopicName

Topic格式错误。

可在控制台设备详情页的Topic列表页签下查看

正确的Topic格式。

iot.prod.NotExistedProduct 产品不存在。

请确认输入的ProductKey正确,并该产品属于当

前阿里云账号。

iot.common.QueryProductActionError 查询产品失败。

请确认入参信息正确,然后重试。

iot.ruleng.IncorrectSysTopic 系统Topic错误。

可在控制台设备详情页的Topic列表页签下查看

正确的Topic。

iot.messagebroker.NullTopicName Topic名称不能为空。

表 1-2: 目标为ONS(消息队列)的错误码

错误码 描述

iot.messagebroker.NullTopicName 消息队列中接收消息的Topic不能为空。

1.1.2.6 产品管理

1.1.2.6.1 CreateProduct调用该接口新建产品。

请求参数

30 文档版本:20200417

Page 43: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

ProductKey String 产品的Key。

Data Data 调用成功时返回的新建产品信息。详情参见下表ProductInfo。

表 1-3: ProductInfo

名称 类型 描述

ProductName String 产品的名称。

ProductKey String 物联网平台为新建产品颁发的产品Key,作为该产品的全局唯一标识。

说明:请妥善保管新建产品的ProductKey。在其他操作中会用到该信息。

Description String 产品描述信息。

DataFormat Integer 产品类型数据格式。

• 0:透传/自定义格式(CUSTOM_FORMAT)。• 1:Alink协议(ALINK_FORMAT)。

此参数为高级版产品的特有参数。

AliyunCommodityCode

String 产品类型。

• iothub_senior:高级版(使用物模型)。• iothub:基础版(不使用物模型)。

ProtocolType String 设备接入网关协议类型。

此参数为高级版产品的特有参数。

文档版本:20200417 31

Page 44: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

NodeType Integer 产品的节点类型,取值:

0:设备。设备不能挂载子设备。可以直连物联网平

台,也可以作为网关的子设备连接物联网平台。

1:网关。网关可以挂载子设备,具有子设备管理模

块,维持子设备的拓扑关系,和将拓扑关系同步到物联

网平台。

此参数为高级版产品的特有参数。

ResourceGroupId String 产品所属资源组ID。

示例

请求示例

返回示例

• JSON格式

{ "Data": { "Description": "Product test", "DataFormat": 1, "ProtocolType": "modbus", "ProductKey": "a1FlqIQ****", "NodeType": 0, "ProductName": "Test", "AliyunCommodityCode": "iothub_senior", "AuthType": "secret", "ResourceGroupId": "rg-acfmxazb4ph****" }, "ProductKey": "a1FlqIQ****", "RequestId": "E55E50B7-40EE-4B6B-8BBE-D3ED55CCF565", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><CreateProductResponse> <Data> <Description>Product test</Description> <DataFormat>1</DataFormat> <ProtocolType>modbus</ProtocolType> <ProductKey>a1FlqIQ****</ProductKey> <NodeType>0</NodeType> <ProductName>Test</ProductName> <AliyunCommodityCode>iothub_senior</AliyunCommodityCode> <AuthType>secret</AuthType> <ResourceGroupId>rg-acfmxazb4ph****</ResourceGroupId> </Data>

32 文档版本:20200417

Page 45: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<ProductKey>a1FlqIQ****</ProductKey> <RequestId>E55E50B7-40EE-4B6B-8BBE-D3ED55CCF565</RequestId> <Success>true</Success></CreateProductResponse>

1.1.2.6.2 QueryProduct调用该接口查询指定产品的详细信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryProduct。

ProductKey String 是 要查询的产品的ProductKey。ProductKey是物联网平台为新建产品颁发的产品Key,作为其全局唯一标识符。您可以在创建产品的返回结果中查看该信息。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情见表格Data。

表 1-4: Data

名称 类型 描述

GmtCreate Long 产品创建时间。

文档版本:20200417 33

Page 46: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

DataFormat Integer 高级版产品的数据类型,指设备与云端之间的数据通信

协议类型。取值:

0:透传模式。使用自定义的串口数据格式。该模式

下,设备可以上报原始数据(如二进制数据流)。阿里

云物联网平台会运行您配置在云端的数据解析脚本,将

原始数据转换成Alink JSON标准数据格式。

1:Alink JSON。阿里云物联网平台定义的设备与云端

的数据交换协议,采用 JSON 格式。

说明:此参数为高级版产品特有参数。

Description String 产品的描述信息。

DeviceCount Integer 该产品下的设备数量。

NodeType Integer 高级版产品的节点类型。取值:

0:设备。设备不能挂载子设备,可以直连IoT Hub,也

可以作为网关的子设备连接IoT Hub。

1:网关。网关可以挂载子设备,具有子设备管理模

块,维持子设备的拓扑关系,并且可以将拓扑关系同步

到云端。

ProductKey String 产品Key。新建产品时,物联网平台为该产品颁发的全局唯一标识。

ProductName String 产品名称。

ProductSecret String 产品密钥。

CategoryName String 高级版产品的设备类型。取值为您在创建高级版产品时,所选择的设备类型。

CategoryKey String 高级版产品的设备类型的英文标识符。

AliyunCommodityCode

String 取值:

• iothub:物联网平台基础版(不使用物模型) 。• iothub_senior:物联网平台高级版(使用物模

型)。

34 文档版本:20200417

Page 47: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

ProtocolType String 设备接入网关的协议类型。

此参数为高级版产品,且产品节点类型为要接入网关的

设备的特有参数。

取值:

• modbus:Modbus协议• opc-ua:OPC UA协议• customize:自定义协议• ble:BLE协议• zigbee:ZigBee协议

ProductStatus String 产品状态。

• DEVELOPMENT_STATUS:开发中。• RELEASE_STATUS:产品已发布。

NetType Integer 联网方式。取值:

• 3:WiFi• 6:Cellular (2G/3G/4G)蜂窝网• 7:Ethernet 以太网。• 8:其他

示例

请求示例

返回示例

• JSON格式

• XML格式

1.1.2.6.3 QueryProductList调用该接口查看所有产品列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryProductList。

CurrentPage Integer 是 指定显示返回结果中的第几页。

PageSize Integer 是 指定返回结果中每页显示的产品数量,最大值是200。

文档版本:20200417 35

Page 48: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

AliyunCommodityCode

String 否 指定要查看的产品类型,取值:

iothub_senior:物联网平台高级版

iothub:物联网平台基础版

说明:如果不传入该参数,则返回所有产品的列表。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的产品列表。详情参见下表Data。

表 1-5: Data

名称 类型 描述

PageSize Integer 每页显示的产品数。

PageCount Integer 总页数。

CurrentPage Integer 当前页号。

Total Integer 当前账号下的产品总数。

List List 产品信息列表。请参见下表ProductInfo。

说明:返回的产品信息按照产品创建时间倒序排列。

36 文档版本:20200417

Page 49: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-6: ProductInfo

名称 类型 描述

DataFormat Integer 数据格式,指设备与云端之间的数据通信协议类型,取

值:

0:透传模式。使用自定义的串口数据格式。该模式下,设

备可以上报原始数据(如二进制数据流),阿里云IoT平

台会运行您配置在云端的数据解析脚本,将原始数据转换

成Alink JSON标准数据格式。

1:Alink JSON。阿里云物联网平台定义的设备与云端的数

据交换协议,采用 JSON 格式。

说明:此参数为高级版产品特有参数。

ProductKey String 产品的Key。新建产品时,物联网平台为该产品颁发的全局唯一标识。

NodeType Integer 产品的节点类型,取值:

0:设备。设备不能挂载子设备,可以直连物联网平台,也

可以作为网关的子设备连接物联网平台。

1:网关。网关可以挂载子设备,具有子设备管理模块,维

持子设备的拓扑关系,并且可以将拓扑关系同步到云端。

ProductName String 产品名称。

DeviceCount Integer 产品下的设备数量。

GmtCreate Long 产品的创建时间。

Description String 产品的描述信息。

示例

请求示例

返回示例

• JSON格式

{ "Data": { "PageCount": 92, "PageSize": 2,

文档版本:20200417 37

Page 50: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"List": { "ProductInfo": [ { "DataFormat": 1, "ProductKey": "a1A0D4t****", "NodeType": 0, "ProductName": "路灯产品", "DeviceCount": 1, "GmtCreate": 1569233025000, "AuthType": "secret" }, { "DataFormat": 1, "ProductKey": "a1dEvuQ****", "NodeType": 0, "ProductName": "子设备custom", "DeviceCount": 0, "GmtCreate": 1568690432000, "AuthType": "secret" } ] }, "CurrentPage": 1, "Total": 184 }, "RequestId": "4B4ECF2C-6222-42EC-A4B5-C12202E71CEA", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8"?><QueryProductListResponse> <Data> <PageCount>92</PageCount> <PageSize>2</PageSize> <List> <ProductInfo> <DataFormat>1</DataFormat> <ProductKey>a1A0D4t****</ProductKey> <NodeType>0</NodeType> <ProductName>路灯产品</ProductName> <DeviceCount>1</DeviceCount> <GmtCreate>1569233025000</GmtCreate> <AuthType>secret</AuthType> </ProductInfo> <ProductInfo> <DataFormat>1</DataFormat> <ProductKey>a1dEvuQ****</ProductKey> <NodeType>0</NodeType> <ProductName>子设备custom</ProductName> <DeviceCount>0</DeviceCount> <GmtCreate>1568690432000</GmtCreate> <AuthType>secret</AuthType> </ProductInfo> </List> <CurrentPage>1</CurrentPage> <Total>184</Total> </Data> <RequestId>4B4ECF2C-6222-42EC-A4B5-C12202E71CEA</RequestId> <Success>true</Success>

38 文档版本:20200417

Page 51: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryProductListResponse>

1.1.2.6.4 UpdateProduct调用该接口修改指定产品的信息。

请求参数

参数 类型 是否必需 描述

Action String 是 要执行的操作,取值:UpdateProduct。

ProductKey String 是 要修改信息的产品的Key。

ProductName

String 是 修改后的产品名称。产品名应满足以下限制:长度为4-30字符,可以包含中文、英文字母、数字和下划线(一个中文字符占两位)。

说明:产品名在当前账号下应具有唯一性。

Description String 否 指定修改后的产品描述信息。描述信息应在100字符以内。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"C4FDA54C-4201-487F-92E9-022F42387458", "Success":true,

文档版本:20200417 39

Page 52: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8"?> <UpdateProductResponse> <RequestId>C4FDA54C-4201-487F-92E9-022F42387458</RequestId> <Success>true</Success></UpdateProductResponse>

1.1.2.6.5 DeleteProduct调用该接口删除指定产品。(产品删除后,产品Key(ProductKey)将失效,与产品关联的其他信息

也一并删除,您将无法执行与该产品关联的任何操作。)

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteProduct。

ProductKey String 是 要删除的产品Key。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true

40 文档版本:20200417

Page 53: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8"?> <DeleteDeviceResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></DeleteDeviceResponse>

1.1.2.6.6 CreateProductTags调用该接口为指定产品创建标签。

限制说明

• 单次调用该接口最多能为指定产品创建10个标签。

• 单个产品的标签总数不超过100个。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值CreateProductTags。

ProductKey String 是 产品Key,物联网平台为产品颁发的唯一标识。

ProductTags List<ProductTag>

是 要创建的标签。标签包括TagKey和TagValue,分别对应标签的key和value。请参见下表ProductTag。

说明:新增标签的TagKey不能重复,也不能和已有标签的key重复。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-7: ProductTag

名称 类型 是否必需 描述

TagKey String 是 产品标签键(key)。可包含英文大小写字母,数字和点号(.),长度不可超过30个字符。

TagValue String 是 产品标签值(value)。可包含中文、英文字母、数字、下划线(_)和连接号(-)。长度不可超过128字符。一个中文汉字算2字符。

文档版本:20200417 41

Page 54: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

InvalidProductTags

List<ProductTag>

调用失败时,返回不合法的产品标签列表。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "354A4F9B-6B01-4498-8084-867F59720BA5", "Success": true}

• XML格式

<CreateProductTagsResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></CreateProductTagsResponse>

1.1.2.6.7 UpdateProductTags调用该接口更新产品标签。

限制说明

单次调用该接口最多可更新10个标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值UpdateProductTags。

ProductKey String 是 产品Key,物联网平台为产品颁发的唯一标识。

42 文档版本:20200417

Page 55: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ProductTags List<ProductTag>

是 要更新的标签。标签包括TagKey和TagValue,分别对应标签的key和value。请参见下表ProductTag。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-8: ProductTag

名称 类型 是否必需 描述

TagKey String 是 产品标签键(key)。可包含英文大小写字母,数字和点号(.),长度不可超过30个字符。

说明:

• 传入标签的TagKey不能重复。• 传入标签的TagKey必须是已存在的标签key

TagValue String 是 产品标签值(value)。可包含中文、英文字母、数字、下划线(_)和连接号(-)。长度不可超过128字符。一个中文汉字算2字符。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

InvalidProductTags

List<String> 调用失败时,返回不合法的产品标签列表。

示例

请求示例

文档版本:20200417 43

Page 56: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回示例

JSON格式

{ "RequestId": "92586B4B-FF78-494A-A22C-368E4293FBB7", "Success": true}

XML格式

<UpdateProductTagsResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></UpdateProductTagsResponse>

1.1.2.6.8 DeleteProductTags调用该接口删除产品标签。

限制说明

单次调用该接口最多可删除10个标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值DeleteProductTags。

ProductKey String 是 产品Key,物联网平台为产品颁发的唯一标识。

ProductTagKeys

List<String> 是 产品标签键列表。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

44 文档版本:20200417

Page 57: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

JSON格式

{ "RequestId": "E7E8456E-EDD7-41D3-83B1-62FF4F5ED6BD", "Success": true}

XML格式

<DeleteProductTagsResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></DeleteProductTagsResponse>

1.1.2.6.9 ListProductTags调用该接口查询指定产品的所有标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值ListProductTags。

ProductKey String 是 产品Key,物联网平台为产品颁发的唯一标识。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data List<String> 调用成功时,返回产品标签信息列表。详情见下表ProductTag。

文档版本:20200417 45

Page 58: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-9: ProductTag

名称 类型 是否必需 描述

TagKey String 是 产品标签键(key)。

TagValue String 是 产品标签值(value)。

示例

请求示例

返回示例

JSON格式

{ "Data": { "ProductTag": [ { "TagValue": "alterTable", "TagKey": "binary" }, { "TagValue": "json2", "TagKey": "extt" }, { "TagValue": "1234", "TagKey": "Lock" }, { "TagValue": "support", "TagKey": "Lockk" }, { "TagValue": "reen", "TagKey": "Reen" }, { "TagValue": "try", "TagKey": "Reenn" }, { "TagValue": "DropTable", "TagKey": "roc" } ] }, "RequestId": "7FBE60F8-4AB5-4A8C-AFCB-F4F38851F01F", "Success": true}

XML格式

<?xml version="1.0" encoding="UTF-8" ?><ListProductTagsResponse> <Data> <ProductTag>

46 文档版本:20200417

Page 59: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<TagValue>alterTable</TagValue> <TagKey>binary</TagKey> </ProductTag> <ProductTag> <TagValue>json2</TagValue> <TagKey>extt</TagKey> </ProductTag> <ProductTag> <TagValue>1234</TagValue> <TagKey>Lock</TagKey> </ProductTag> <ProductTag> <TagValue>support</TagValue> <TagKey>Lockk</TagKey> </ProductTag> <ProductTag> <TagValue>reen</TagValue> <TagKey>Reen</TagKey> </ProductTag> <ProductTag> <TagValue>try</TagValue> <TagKey>Reenn</TagKey> </ProductTag> <ProductTag> <TagValue>DropTable</TagValue> <TagKey>roc</TagKey> </ProductTag> </Data> <RequestId>7FBE60F8-4AB5-4A8C-AFCB-F4F38851F01F</RequestId> <Success>true</Success></ListProductTagsResponse>

1.1.2.6.10 ListProductByTags调用该接口根据标签分页查询产品列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值ListProductByTags。

ProductTags List<String> 是 产品标签。ProductTag包括TagKey和TagValue,分别对应标签的key和value。请参见下表ProductTag。

• 支持按照TagKey和TagValue组合来搜索。• 支持只按照TagKey来搜索。• 传入多个ProductTag是或的关系。

PageSize Integer 否 指定返回结果中每页显示的记录数量。最大值是50。默认值是10。

CurrentPage Integer 否 指定显示返回结果中的第几页。默认值为1。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

文档版本:20200417 47

Page 60: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

公共请求参数 - 是 请参见公共参数。

表 1-10: ProductTag

名称 类型 是否必需 描述

TagKey String 是 产品标签键(key)。

TagValue String 否 产品标签值(value)。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

ProductInfos List<String> 调用成功时,返回产品信息列表。详情见下表ProductInfo。

说明:返回的产品信息按照产品创建时间倒序排列。

表 1-11: ProductInfo

名称 类型 描述

ProductKey String 产品Key。

ProductName String 产品名称。

NodeType Integer 节点类型。

CreateTime Long 产品创建时间。

Description String 产品描述。

示例

请求示例

返回示例

48 文档版本:20200417

Page 61: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

JSON格式

{ "ProductInfos": { "ProductInfo": [ { "Description": "Bulbs in the rooms", "ProductKey": "a1h7knJ****", "NodeType": 0, "CreateTime": 1545355537000, "ProductB: "Bulbs" } ] }, "RequestId": "2E410BE3-C688-487B-9BF1-F04B33632CCC", "Success": true}

XML格式

<ListProductByTagsResponse> <ProductInfos> <ProductInfo> <Description>Bulbs in the rooms</Description> <ProductKey>a1h7knJ****</ProductKey> <NodeType>0</NodeType> <CreateTime>1545355537000</CreateTime> <ProductName>Bulbs</ProductName> </ProductInfo> </ProductInfos> <RequestId>2E410BE3-C688-487B-9BF1-F04B33632CCC</RequestId> <Success>true</Success></ListProductByTagsResponse>

1.1.2.7 设备管理

1.1.2.7.1 RegisterDevice调用该接口在指定产品下注册设备。

接口说明

注册设备指在物联网平台产品下添加设备。在指定产品下成功注册设备后,阿里云物联网平台为设备

颁发全局唯一的设备ID(IotId),用来标识该设备。在进行与设备相关的操作时,您可能需要提供

目标设备的IotId。

说明:

除了IotId,您也可以使用ProductKey和DeviceName组合来标识一个设备。其中ProductKey是

新建产品时物联网平台为产品颁发的产品Key,DeviceName是注册设备时由您指定或由系统随机

生成的设备名称。IotId的优先级高于ProductKey和DeviceName组合。

• 如果您希望在一个产品下批量注册多个设备,并且随机生成设备名,您可以调

用BatchRegisterDevice接口。

文档版本:20200417 49

Page 62: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 如果您希望在一个产品下批量注册多个设备,并且为每个设备单独命名,您需要先调

用BatchCheckDeviceNames接口为每个设备命名,并生成申请批次ID(ApplyId),再调

用BatchRegisterDeviceWithApplyId接口批量注册设备。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:RegisterDevice。

ProductKey String 是 待注册设备所隶属的产品的Key,即产品的唯一标识符。

DeviceName String 否 为待注册的设备命名。设备名称长度为4-

32个字符,可以包含英文字母、数字和特

殊字符:连字符(-)、下划线(_)、at符

号(@)、点号(.)、和英文冒号(:)。

DeviceName通常与ProductKey组合使

用,用作标识具体的设备。

说明:如果不传入该参数,则由系统随机生成设备名称。

Nickname String 否 为待注册的设备设置备注名称。备注名称长度为4-64个字符,可包含中文汉字、英文字母、数字和下划线(_)。一个中文汉字算2字符。

说明:如果不传入该参数,系统不会为设备生成备注名称

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

50 文档版本:20200417

Page 63: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回注册的设备信息。详情参见下表DeviceInfo。

表 1-12: DeviceInfo

名称 类型 描述

ProductKey String 设备隶属的产品Key。

DeviceName String 设备名称。

说明:请妥善保管该信息。

DeviceSecret String 设备密钥。

说明:请妥善保管该信息。

IotId String 物联网平台为该设备颁发的设备ID,作为该设备的唯一标

识符。

说明:请妥善保管该信息。

Nickname String 设备的备注名称。

若您没有为该设备设置备注名称,则该参数返回为空。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "DeviceName": "device1", "ProductKey": "a1rYuVF****", "DeviceSecret": "tXHf4ezGEHcwdyMwoCDHGBmk9avi****",

文档版本:20200417 51

Page 64: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"IotId": "CqXL5h5ysRTA4NxjABjj0010fa****", "Nickname": "detectors_in_beijing" }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><RegisterDeviceResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <DeviceName>device1</DeviceName> <ProductKey>a1rYuVF****</ProductKey> <DeviceSecret>tXHf4ezGEHcwdyMwoCDHGBmk9avi****</DeviceSecret> <IotId>CqXL5h5ysRTA4NxjABjj0010fa****</IotId> <Nickname>detectors_in_beijing</Nickname> </Data></RegisterDeviceResponse>

1.1.2.7.2 QueryDeviceDetail调用该接口查询指定设备的详细信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceDetail。

IotId String 否 要查询的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,和ProductKey与DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 指定要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

52 文档版本:20200417

Page 65: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回设备的详细信息。详情请参见下表Data。

表 1-13: Data

名称 类型 描述

ProductKey String 设备隶属的产品Key。

ProductName String 设备隶属的产品名称。

DeviceName String 设备名称。

Nickname String 设备的备注名称。

DeviceSecret String 设备密钥。

IotId String IoT平台为该设备颁发的ID,作为该设备的唯一标识符。

UtcCreate String 设备的创建时间(UTC)。

GmtCreate String 设备的创建时间(GMT)。

UtcActive String 设备的激活时间(UTC)。

GmtActive String 设备的激活时间(GMT)。

UtcOnline String 设备最近一次上线的时间(UTC)。

GmtOnline String 设备最近一次上线的时间(GMT)。

文档版本:20200417 53

Page 66: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Status String 设备状态。取值:

ONLINE:设备在线。

OFFLINE:设备离线。

UNACTIVE:设备未激活。

DISABLE:设备已禁用。

FirmwareVersion

String 设备的固件版本号。

IpAddress String 设备的IP地址。

NodeType Integer 节点类型,取值:

0:设备。设备不能挂载子设备,可以直连IoT Hub,也可

以作为网关的子设备连接IoT Hub。

1:网关。网关可以挂载子设备,具有子设备管理模块,维

持子设备的拓扑关系,并且可以将拓扑关系同步到云端。

Region String 设备所在地区(与控制台上的物联网地平台服务地域对应)。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "DeviceName": "device1", "GmtActive": "2018-08-06 10:48:41", "UtcActive": "2018-08-06T02:48:41.000Z", "ProductKey": "a1rYuVF****", "DeviceSecret": "CPwUjMUgzdvaZv56TMy6773V3v3****", "Nickname": "detectors_in_beijing", "GmtCreate": "2018-08-06 10:47:50", "UtcCreate": "2018-08-06T02:47:50.000Z", "IotId": "SR8FiTu1R9tlUR2V1bmi00105****", "Status": "ONLINE", "Region": "cn-shanghai", "NodeType": 0, "GmtOnline": "2018-08-06 13:43:12", "UtcOnline": "2018-08-06T05:43:12.000Z",

54 文档版本:20200417

Page 67: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"ProductName": "test", "IpAddress": "10.0.0.1", "FirmwareVersion": "V1.0" }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryDeviceDetailResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <DeviceName>device1</DeviceName> <GmtActive>2018-08-06 10:48:41</GmtActve> <UtcActive>2018-08-06T02:48:41.000Z</UtcActive> <ProductKey>a1rYuVF****</ProductKey> <DeviceSecret>CPwUjMUgzdvaZv56TMy6773V3v3****</DeviceSecret> <Nickname>detectors_in_beijing</Nickname> <GmtCreate>2018-08-06 10:47:50</GmCreate> <UtcCreate>2018-08-06T02:47:50.000Z</UtcCreate> <IotId>SR8FiTu1R9tlUR2V1bmi0010a5****</IotId> <Status>ONLINE</Status> <Region>cn-shanghai</Region> <NodeType>0</NodeType> <GmtOnline>2018-08-06 13:43:2</GmtOnline> <UtcOnline>2018-08-06T05:43:12.000Z</UtcOnline> <ProductName>test</ProductName> <IpAddress>10.0.0.1</IpAddress> <FirmwareVersion>V1.0</FirmwareVersion> </Data></QueryDeviceDetailResponse>

1.1.2.7.3 BatchQueryDeviceDetail调用该接口批量查询设备详情。

限制说明

• 单次调用最多能查询100个设备。

• 只能批量查询当前阿里云账号下的设备详情。如果传入的设备信息中,有设备不属于当前账

号,则直接返回失败结果。

• 若传入的设备信息中,包含不存在的设备,则只返回存在的设备详情。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:BatchQueryDeviceDetail。

ProductKey String 是 要查询的设备所隶属的产品Key。

文档版本:20200417 55

Page 68: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceName List<String> 是 指定要查询的设备名称列表。最多可包含100个

设备名称。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回设备的详细信息。详情请参见下表DeviceInfo。

表 1-14: DeviceInfo

名称 类型 描述

ProductKey String 设备隶属的产品Key。

ProductName String 设备隶属的产品名称。

DeviceName String 设备名称。

Nickname String 设备的备注名称。

DeviceSecret String 设备密钥。

IotId String 物联网平台为该设备颁发的ID,设备的唯一标识符。

UtcCreate String 设备的创建时间(UTC)。

GmtCreate String 设备的创建时间(GMT)。

UtcActive String 设备的激活时间(UTC)。

GmtActive String 设备的激活时间(GMT)。

56 文档版本:20200417

Page 69: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Status String 设备状态。取值:

ONLINE:设备在线。

OFFLINE:设备离线。

UNACTIVE:设备未激活。

DISABLE:设备已禁用。

FirmwareVersion

String 设备的固件版本号。

NodeType Integer 节点类型,取值:

0:设备。设备不能挂载子设备,可以直接连接到物联网平

台,也可以作为网关的子设备连接到物联网平台。

1:网关。网关可以挂载子设备,具有子设备管理模块,维

持子设备的拓扑关系,并且可以将拓扑关系同步到云端。

Region String 设备所在地域(与控制台上物联网平台服务地域对应)。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "57b144cf-09fc-4916-a272-a62902d5b787", "Success": true, "Data":[ { "DeviceName": "firstDeviceName", "DeviceSecret": "m2gIah1iCkIHXqVJdBVM****", "FirmwareVersion": "v1.0.0", "GmtCreate": "2019-06-21 20:31:42", "GmtActive": "2019-06-21 20:33:00", "IotId": "M7aUr3JmdsJ1KQolwI3l00****", "Nickname": "TestDevice1", "NodeType": 0, "ProductKey": "a1fce6J****", "ProductName": "testProduct2b2ea8", "Region": "cn-shanghai", "Status": "ONLINE", "UtcCreate": "2019-06-21T12:31:42.000Z", "UtcActive": "2019-06-21T12:33:00.000Z", }, {

文档版本:20200417 57

Page 70: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"DeviceName": "secondDeviceName", "DeviceSecret": "i7nIah1iCkIHXqVJdBVM****", "GmtCreate": "2019-06-21 20:31:42", "IotId": "ioUyd3JmdsJ1KQolwI3l00****", "NodeType": 0, "ProductKey": "a1fce6J****", "ProductName": "testProduct2b2ea8", "Region": "cn-shanghai", "Status": "UNACTIVE", "UtcCreate": "2019-06-21T12:31:42.000Z" } ]}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><BatchQueryDeviceDetailResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b787</RequestId> <Success>true</Success> <Data> <DeviceName>firstDeviceName</DeviceName> <DeviceSecret>m2gIah1iCkIHXqVJdBVM****</DeviceSecret> <FirmwareVersion>v1.0.0</FirmwareVersion> <GmtCreate>2019-06-21 20:31:42</GmtCreate> <GmtActive>2019-06-21 20:33:00</GmtActive> <IotId>M7aUr3JmdsJ1KQolwI3l00****</IotId> <Nickname>TestDevice1</Nickname> <NodeType>0</NodeType> <ProductKey>a1fce6J****</ProductKey> <ProductName>testProduct2b2ea8</ProductName> <Region>cn-shanghai</Region> <Status>ONLINE</Status> <UtcCreate>2019-06-21T12:31:42.000Z</UtcCreate> <UtcActive>2019-06-21T12:33:00.000Z</UtcActive> </Data> <Data> <DeviceName>secondDeviceName</DeviceName> <DeviceSecret>i7nIah1iCkIHXqVJdBVM****</DeviceSecret> <GmtCreate>2019-06-21 20:31:42</GmtCreate> <IotId>ioUyd3JmdsJ1KQolwI3l00****</IotId> <NodeType>0</NodeType> <ProductKey>a1fce6J****</ProductKey> <ProductName>testProduct2b2ea8</ProductName> <Region>cn-shanghai</Region> <Status>UNACTIVE</Status> <UtcCreate>2019-06-21T12:31:42.000Z</UtcCreate> </Data></BatchQueryDeviceDetailResponse>

1.1.2.7.4 QueryDevice调用该接口查询指定产品下的所有设备列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDevice。

ProductKey String 是 要查询的设备所隶属的产品Key。

58 文档版本:20200417

Page 71: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

PageSize Integer 否 指定返回结果中每页显示的记录数量,最大值是50。默认值是10。

CurrentPage Integer 否 指定显示返回结果中的第几页的内容。默认值是 1。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

PageCount Integer 总页数。

PageSize Integer 每页显示的记录数。

Page Integer 当前页面号。

Total Integer 总记录数。

Data Data 调用成功时,返回设备信息列表。详情参见下表DeviceInfo。

说明:返回的设备信息按照设备创建时间倒序排列。

表 1-15: DeviceInfo

名称 类型 描述

DeviceId String 设备ID(旧版参数)。

说明:该参数是旧版本遗留参数,已无实际作用,不能用来标识设备。目前,有效的设备标识符为IotId和ProductKey 与DeviceName组合。

文档版本:20200417 59

Page 72: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

DeviceName String 设备名称。

ProductKey String 设备所属产品Key,即物联网平台为该产品颁发的唯一标识。

DeviceSecret String 设备密钥。

GmtCreate String 设备创建GMT时间。

GmtModified String 设备信息修改GMT时间。

UtcCreate String 设备创建UTC时间。

UtcModified String 设备信息修改UTC时间。

DeviceStatus String 设备状态。

IotId String 设备ID,物联网平台为设备颁发的唯一标识。

Nickname String 设备的备注名称。

示例

请求示例

返回示例

• JSON格式

{ "PageCount": 1, "Data": { "DeviceInfo": [ { "DeviceId": "Av8NGHGtwPrH9BYG****", "DeviceName": "Av8NGHGtwPrH9BYGLMBi", "ProductKey": "a1dafDE****", "DeviceSecret": "d7GYhf5hfcPHDe1bXSd3n9MjO1G3****", "UtcModified": "2019-02-20T02:16:09.000Z", "GmtCreate": "Wed, 20-Feb-2019 02:16:09 GMT", "UtcCreate": "2019-02-20T02:16:09.000Z", "GmtModified": "Wed, 20-Feb-2019 02:16:09 GMT", "IotId": "Av8NGHGtwPrH9BYGLMBi00****", "DeviceStatus": "UNACTIVE", "Nickname": "SensorInShanghai" }, { "DeviceId": "zNIcSmWQ9BPJlmkj****", "DeviceName": "zNIcSmWQ9BPJlmkjn3H1", "ProductKey": "a1dafDE****", "DeviceSecret": "C27XXmC18yLIEDXvUj6FSlvgO7ag****", "UtcModified": "2019-02-20T02:16:09.000Z", "GmtCreate": "Wed, 20-Feb-2019 02:16:09 GMT", "UtcCreate": "2019-02-20T02:16:09.000Z", "GmtModified": "Wed, 20-Feb-2019 02:16:09 GMT", "IotId": "zNIcSmWQ9BPJlmkjn3H100****", "DeviceStatus": "UNACTIVE", "Nickname": "DriverInShanghai"

60 文档版本:20200417

Page 73: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

} ] }, "Page": 1, "PageSize": 10, "RequestId": "CD9E5F99-A095-4A05-9256-D924EA3075E8", "Success": true, "Total": 2}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceResponse> <PageCount>1</PageCount> <Data> <DeviceInfo> <DeviceId>VIjUsKaJsdWqt6nl****</DeviceId> <DeviceName>led_device</DeviceName> <ProductKey>a1dafDE****</ProductKey> <DeviceSecret>qQP6xARs7ky1HuM2reh7y6M4BTdfe****</DeviceSecret> <UtcModified>2019-02-19T10:20:14.000Z</UtcModified> <GmtCreate>Wed, 30-Jan-2019 11:32:39 GMT</GmtCreate> <UtcCreate>2019-01-30T11:32:39.000Z</UtcCreate> <GmtModified>Tue, 19-Feb-2019 10:20:14 GMT</GmtModified> <DeviceStatus>OFFLINE</DeviceStatus> <IotId>nadRfljdEndlfadgadfse****</IotId> <Nickname>SensorInShanghai</Nickname> </DeviceInfo> <DeviceInfo> <DeviceId>QwTxRbhFwcaJBad****</DeviceId> <DeviceName>led_driver</DeviceName> <ProductKey>a1dafDE****</ProductKey> <DeviceSecret>6ahkx2cOd0kVPsjnVmxYaGEhMfdf****</DeviceSecret> <UtcModified>2019-01-30T11:10:10.000Z</UtcModified> <GmtCreate>Wed, 30-Jan-2019 11:10:10 GMT</GmtCreate> <UtcCreate>2019-01-30T11:10:10.000Z</UtcCreate> <GmtModified>Wed, 30-Jan-2019 11:10:10 GMT</GmtModified> <DeviceStatus>UNACTIVE</DeviceStatus> <IotId>nadddfRddfaEEadfed****</IotId> <Nickname>DriverInShanghai</Nickname> </DeviceInfo> </Data> <PageSize>10</PageSize> <RequestId>A4F5820D-E2B3-48D4-AAF8-53FF6A319E27</RequestId> <Success>true</Success> <Total>2</Total></QueryDeviceResponse>

1.1.2.7.5 DeleteDevice调用该接口删除指定设备。

说明

• 设备删除后,设备ID(IotId)将失效,与设备关联的其他信息也一并删除,您将无法执行与该设

备关联的任何操作。

• 传入请求参数时,需传入IotId或ProductKey与DeviceName组合,用于指定设备。

文档版本:20200417 61

Page 74: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteDevice。

IotId String 否 要删除的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要删除的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 指定要删除的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

62 文档版本:20200417

Page 75: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true}

• XML示例

<?xml version="1.0" encoding="UTF-8"?> <DeleteDeviceResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></DeleteDeviceResponse>

1.1.2.7.6 GetDeviceStatus调用该接口查看指定设备的运行状态。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:GetDeviceStatus。

IotId String 否 要查看运行状态的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey&DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查看运行状态的设备隶属的产品的Key。

说明:如果传入该参数,需同时传入DeviceName。

文档版本:20200417 63

Page 76: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceName String 否 指定要查看运行状态的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回设备状态信息。详情参见下表DeviceStatusInfo。

表 1-16: DeviceStatusInfo

名称 类型 描述

Status String 设备状态。取值:

ONLINE:设备在线。

OFFLINE:设备离线。

UNACTIVE:设备未激活。

DISABLE:设备已禁用。

示例

请求示例

返回示例

64 文档版本:20200417

Page 77: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true "Data": { "Status": "UNACTIVE" } }

• XML格式

<?xml version='1.0' encoding='utf-8'?><GetDeviceStatusResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <Status>UNACTIVE</Status> </Data></GetDeviceStatusResponse>

1.1.2.7.7 BatchGetDeviceState调用该接口批量查看同一产品下指定设备的运行状态。

限制说明

该接口用于查看一个产品下多个设备的运行状态,单次最多可查询50个设备。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:BatchGetDeviceState。

ProductKey String 否 要查看运行状态的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceNames

List<String> 否 要查看运行状态的设备的名称列表。

说明:

• 如果传入该参数,需同时传入ProductKey。

• 最多可传入50个设备名称。

文档版本:20200417 65

Page 78: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

IotIds List 否 要查看运行状态的设备ID列表。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey 和 DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

DeviceStatusList List 调用成功时,返回设备状态信息列表。详情参见下表DeviceStatus。

表 1-17: DeviceStatus

名称 类型 描述

DeviceName String 设备名称。

Status String 设备状态。取值:

ONLINE:设备在线。

OFFLINE:设备离线。

UNACTIVE:设备未激活。

DISABLE:设备已禁用。

66 文档版本:20200417

Page 79: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

DeviceId String 设备ID(旧版参数)。

说明:该参数是旧版本遗留参数,已无实际作用,不能用来标识设备。目前,有效的设备标识符为IotId和ProductKey 与DeviceName组合。

IotId String 设备ID,物联网平台为设备颁发的唯一标识。

示例

请求示例

返回示例

• JSON格式

{ "DeviceStatusList": { "DeviceStatus": [ { "Status": "UNACTIVE", "DeviceId": "xHkR9exGvarIjZ******", "DeviceName": "device1", "IotId": "xHkR9exGvarIjZzpZ0H******" }, { "Status": "UNACTIVE", "DeviceId": "YXMl37sPvABrJy******", "DeviceName": "device2", "IotId": "YXMl37sPvABrJyqoKP******" } ] }, "RequestId": "D9E3DADE-5B9D-4594-AE0E-8090C16B485D", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><BatchGetDeviceStateResponse> <DeviceStatusList> <DeviceStatus> <Status>UNACTIVE</Status> <DeviceId>xHkR9exGvarIjZz******</DeviceId> <DeviceName>device1</DeviceName> <IotId>xHkR9exGvarIjZzpZ0HW******</IotId> </DeviceStatus> <DeviceStatus> <Status>UNACTIVE</Status> <DeviceId>YXMl37sPvABrJy******</DeviceId> <DeviceName>device2</DeviceName> <IotId>YXMl37sPvABrJyqoKP2o******</IotId> </DeviceStatus>

文档版本:20200417 67

Page 80: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</DeviceStatusList> <RequestId>D9E3DADE-5B9D-4594-AE0E-8090C16B485D</RequestId> <Success>true</Success></BatchGetDeviceStateResponse>

1.1.2.7.8 DisableThing调用该接口禁用指定设备。

设备被禁用后将不能接入物联网平台,您将无法执行与设备有关的操作,但与设备关联的信息依然保

留。您可以调用EnableThing接口重新接入被禁用的设备。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DisableThing。

IotId String 否 要禁用的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要禁用的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceNameString 否 指定禁用的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId

String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数

- 是 公共请求参数,请参见公共参数 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

68 文档版本:20200417

Page 81: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true}

• XML格式

<?xml version='1.0' encoding='utf-8'?><DisableThingResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></DisableThingResponse>

1.1.2.7.9 EnableThing调用该接口解除指定设备的禁用状态,即启用被禁用的设备。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:EnableThing。

IotId String 否 要解除禁用的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

文档版本:20200417 69

Page 82: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ProductKey String 否 要解除禁用的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceNameString 否 要解除禁用的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId

String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数

- 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true}

• XML格式

<?xml version='1.0' encoding='utf-8'?><EnableThingResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success>

70 文档版本:20200417

Page 83: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</EnableThingResponse>

1.1.2.7.10 BatchCheckDeviceNames调用该接口在指定产品下批量自定义设备名称。物联网平台将检查名称的合法性。

限制说明

单次调用,最多能定义1,000 个设备名称。

接口使用说明

该接口和BatchRegisterDeviceWithApplyId接口结合使用,在一个产品下批量注册多个设备,并

且为每个设备单独命名。

批量注册设备流程:

1. 调用本接口,传入要批量注册的设备的名称,物联网平台返回申请批次ID(ApplyId)。返回成

功结果,表示批量校验设备名称的申请已经提交成功。实际的校验是异步执行的,会有一个过

程。

2. 调用QueryBatchRegisterDeviceStatus查看名称设置结果。

3. 调用BatchRegisterDeviceWithApplyId批量注册设备。

4. (可选)调用QueryBatchRegisterDeviceStatus查看设备注册结果。

5. 调用QueryPageByApplyId查看批量注册的设备信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:BatchCheckDeviceNames。

ProductKey String 是 要批量注册的设备所隶属的产品Key。

DeviceName List<String> 是 要批量注册的设备的名称列表。每个设备名称

应包含4-32个字符,可以包含英文字母、数字

和特殊字符(连字符、下划线、@符号、点号、

和英文冒号)。

说明:单次调用,最多能传入1,000个设备名称。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

文档版本:20200417 71

Page 84: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

Data Data 调用成功时,返回的数据。详情见下表Data。

表 1-18: Data

名称 类型 描述

ApplyId Long 调用成功时,系统返回的申请批次ID。使用该ApplyId,调用BatchRegisterDeviceWithApplyId接口来批量创建设备。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "ApplyId": 4399 }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><BatchCheckDeviceNamesResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <ApplyId>4401</ApplyId> </Data>

72 文档版本:20200417

Page 85: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</BatchCheckDeviceNamesResponse>

1.1.2.7.11 BatchRegisterDeviceWithApplyId调用该接口根据申请批次ID(ApplyId)批量注册设备。

说明

批量注册设备有两种方式:

• 由系统随机生成设备名称:请调用BatchRegisterDevice接口。

• 自定义设备名称:需本接口与BatchCheckDeviceNames等接口结合实现。

请按以下流程操作。

1. 调用BatchCheckDeviceNames接口,传入要批量注册的设备的名称。物联网平台检查您提交

的设备名称符合要求后,返回申请批次ID(ApplyId)。ApplyId将用于设备名称设置结果查

询、批量设备注册和设备信息查询。

2. 调用QueryBatchRegisterDeviceStatus查看设备名称设置结果。

3. 调用本接口批量注册设备。本接口调用返回的成功结果,仅表示批量注册的申请已经提交成

功。实际的注册会有一个过程。

4. (可选)调用QueryBatchRegisterDeviceStatus查看设备注册结果。

5. 调用QueryPageByApplyId查看批量注册的设备信息(DeviceName、DeviceSecret、IotId

)。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:BatchRegisterDeviceWithApplyId。

ProductKey String 是 要批量注册的设备所隶属的产品Key。

ApplyId Long 是 要批量注册的设备的申请批次ID。申请批次ID由调用BatchCheckDeviceNames接口返回。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

文档版本:20200417 73

Page 86: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情见下表Data。

表 1-19: Data

名称 类型 描述

ApplyId Long 传入的申请批次ID。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "ApplyId": 4416 }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><BatchRegisterDeviceWithApplyIdResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <ApplyId>4416</ApplyId> </Data></BatchRegisterDeviceWithApplyIdResponse>

1.1.2.7.12 BatchRegisterDevice调用该接口在指定产品下批量注册多个设备(随机生成设备名)。

限制说明

单次调用,最多可创建1,000 个设备。

74 文档版本:20200417

Page 87: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

说明

批量注册设备有两种方式:

• 由系统随机生成设备名称:调用本接口。

建议按照以下流程注册设备和查看结果。

1. 调用本接口批量注册设备。

返回成功结果,表示批量注册的申请已经提交成功。实际的注册是异步执行,会有一个过程。

2. 调用QueryBatchRegisterDeviceStatus查看设备注册结果。

3. 调用QueryPageByApplyId查看批量注册的设备信

息(DeviceName、DeviceSecret、IotId)。

• 自定义设备名称:请参见BatchRegisterDeviceWithApplyId。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:BatchRegisterDevice。

ProductKey String 是 要批量注册的设备所隶属的产品Key。

Count Integer 是 要注册的设备数量,取值不能大于1,000。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情见下表Data。

文档版本:20200417 75

Page 88: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-20: Data

名称 类型 描述

ApplyId Long 调用成功时,系统返回的申请批次ID。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "ApplyId": 4415 }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><BatchRegisterDeviceResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <ApplyId>4415</ApplyId> </Data></BatchRegisterDeviceResponse>

1.1.2.7.13 BatchUpdateDeviceNickname调用该接口批量修改设备备注名称。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:BatchUpdateDeviceNickname。

76 文档版本:20200417

Page 89: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceNicknameInfo

List<String> 是 包含设备标识参数(ProductKey和DeviceName组合或IotId)和备注名称参数(Nickname)。

说明:

• 设备标识信息为必传参数,用于指定设备。

• Nickname为非必填参数。若不传入,则删除该设备的原有备注名称。

详情请见下表DeviceNicknameInfo。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数 。

表 1-21: DeviceNicknameInfo

名称 类型 是否必需 描述

IotId String 否 要修改别名的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,和ProductKey与DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要修改别名的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要修改别名的的设备名称。

说明:如果传入该参数,需同时传入ProductKey。

文档版本:20200417 77

Page 90: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Nickname String 否 新的设备备注名称。备注名称长度为4-32个字符,可包含中文汉字、英文字母、数字和下划线(_)。一个中文汉字算2字符。

说明:若不传入该参数,则删除该设备的原有备注名称。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8"?><BatchUpdateDeviceNicknameResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success>

78 文档版本:20200417

Page 91: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</BatchUpdateDeviceNicknameResponse>

1.1.2.7.14 QueryBatchRegisterDeviceStatus调用该接口查询批量注册设备申请的处理状态和结果。

说明

目前,仅华东2(cn-shanghai)地域支持设备X.509证书,如果地域不是华东2(cn-

shanghai),则不能生成X.509证书,返回错误码iot.device.RegionNotSupportX509。

请求参数

名称 类型 是否必须 描述

Action String 是 要执行的操作,取值:QueryBatchRegisterDeviceStatus。

ProductKey String 是 要查询的设备所隶属的产品Key。

ApplyId Long 是 要查询的申请批次ID。申请批次ID在成功调用BatchRegisterDeviceWithApplyId或BatchRegisterDevice接口的返回结果中。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的状态信息。详情参见下表DeviceApplyStatusInfo。

文档版本:20200417 79

Page 92: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-22: DeviceApplyStatusInfo

名称 类型 描述

Status String 申请单的处理状态和结果,取值:

• CHECK:正在校验。• CHECK_SUCCESS:校验成功。• CHECK_FAILED:校验失败。• CREATE:正在创建。• CREATE_SUCCESS:创建成功。

说明:当设备所属产品的认证类型是X.509证书时,表示所有设备和对应的X.509证书都创建成功。

• CREATE_FAILED:创建失败。

说明:当设备所属产品的认证类型是X.509时,只要当前批次中,任意一个设备或X.509证书创建失败,则返回创建失败。

ValidList List • 当返回Status参数值为CHECK_FAILED或CREATE_FAILED时,返回创建成功的设备名称集合。

• 当返回Status参数值为CHECK_SUCCESS或CREATE_SUCCESS时,该参数为空数组。

InvalidList List • 当返回Status参数值为CHECK_FAILED或CREATE_FAILED时,返回创建失败的设备名称集合。

• 当返回Status参数值为CHECK_SUCCESS或CREATE_SUCCESS时,该参数为空数组。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "Status": "CREATE_SUCCESS", "ValidList": { "Name": [

80 文档版本:20200417

Page 93: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

] }, "InvalidList": { "Name": [

] } }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryBatchCheckDeviceNamesStatusResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <Status>CREATE_SUCCESS</Status> <ValidList/> <InvalidList/> </Data></QueryBatchCheckDeviceNamesStatusResponse>

1.1.2.7.15 QueryPageByApplyId调用该接口查询批量注册的设备信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryPageByApplyId。

ApplyId Long 是 要查询的申请批次ID。申请批次ID可在BatchRegisterDeviceWithApplyId和BatchRegisterDevice接口返回结果中查看。

PageSize Integer 否 指定返回结果中每页显示的记录数量。数量限制:每页最多可显示50条。默认值是10。

CurrentPage Integer 否 指定从返回结果中的第几页开始显示。默认值是1。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

文档版本:20200417 81

Page 94: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

PageCount Integer 总页数。

PageSize Integer 每页显示的记录数。

Page Integer 当前页面号。

Total Integer 总记录数。

ApplyDeviceList List 调用成功时生成的已注册的设备列表。详情参见下表ApplyDeviceInfo。

表 1-23: ApplyDeviceInfo

名称 类型 描述

DeviceId String 设备ID(旧版)。

说明:该参数是旧版本遗留参数,已无实际作用,不能用来标识设备。目前,有效的设备标识符为IotId和ProductKey 与DeviceName组合。

DeviceName String 设备名称。

DeviceSecret String 设备密钥。

说明:请妥善保管该信息。

IotId String 设备ID,物联网平台为该设备颁发的唯一标识符。

说明:请妥善保管该信息。

示例

请求示例

返回示例

82 文档版本:20200417

Page 95: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "PageCount": 1, "ApplyDeviceList": { "ApplyDeviceInfo": [ { "DeviceId": "gQG2GJ2y10m6hIk87jFm", "DeviceName": "test1", "DeviceSecret": "SkfeXXKrTgp1DbDxYr74mfJ5cnui****", "IotId": "nadRfljdEndlfadgadfaj****" }, { "DeviceId": "STGEURQaU1o794X7Kh4C", "DeviceName": "test2", "DeviceSecret": "QJxYeGXrif7nfxjyWPA1Qss5CFjO****", "IotId": "nddRfljdFndlfsdfaHfaj****" } ] }, "Page": 1, "PageSize": 10, "RequestId": "6C5DCB26-47A5-4CE0-BDC4-AD74782BC3A9", "Success": true, "Total": 2}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryPageByApplyIdResponse> <PageCount>1</PageCount> <ApplyDeviceList> <ApplyDeviceInfo> <DeviceId>gQG2GJ2y10m6hIk87jFm</DeviceId> <DeviceName>test1</DeviceName> <DeviceSecret>SkfeXXKrTgp1DbDxYr74mfJ5cnui****</DeviceSecret> <IotId>nadRfljdEndlfadgadfaj****</IotId> </ApplyDeviceInfo> <ApplyDeviceInfo> <DeviceId>STGEURQaU1o794X7Kh4C</DeviceId> <DeviceName>test2</DeviceName> <DeviceSecret>QJxYeGXrif7nfxjyWPA1Qss5CFjO****</DeviceSecret> <IotId>nddRfljdFndlfsdfaHfaj****</IotId> </ApplyDeviceInfo> </ApplyDeviceList> <Page>1</Page> <PageSize>10</PageSize> <RequestId>6C5DCB26-47A5-4CE0-BDC4-AD74782BC3A9</RequestId> <Success>true</Success> <Total>2</Total></QueryPageByApplyIdResponse>

1.1.2.7.16 QueryDeviceEventData调用该接口查询指定设备的事件记录。

限制说明

仅能查询最近30天内的事件记录数据。

文档版本:20200417 83

Page 96: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

说明:

数据存储时间从事件生成当日起开始计算。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceEventData。

IotId String 否 要查询的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

EventType String 否 要查询的事件类型。取值:

info:信息。

alert:告警。

error:故障。

Identifier String 是 要查询的事件标识符。设备的事件Identifier,可在控制台中设备所属的产品的功能定义中查看。

84 文档版本:20200417

Page 97: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

StartTime Long 是 要查询的事件记录的开始时间。格式为毫秒级的13位时间戳,例如1516538300303L。

说明:只能查询最近30天内的数据。

EndTime Long 是 要查询的事件记录的结束时间。格式为毫秒级的13位时间戳,例如1516541900303L。

PageSize Integer 否 返回结果中每页显示的记录数。数量限制:每页最多可显示50条。默认值是10。

Asc Integer 否 返回结果中事件记录的排序方式,取值:

0:倒序。

1:正序。

默认值是1(正序)。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

Data Data 调用成功时,返回的设备事件记录。详情参见下表Data。

表 1-24: Data

名称 类型 描述

List List<EventInfo> 事件集合。每个元素代表一个事件。元素的结构参见下表EventInfo。

文档版本:20200417 85

Page 98: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

NextValid Boolean 是否有下一页事件记录。true表示有,false表示没有。

返回NextValid为true时,可以将NextTime的值作为下次

查询的StartTime,继续查询本次查询不显示的数据。

NextTime Long 下一页面中的事件记录的起始时间。

调用本接口查询下一页事件记录时,该值可作为入参

StartTime的值。

表 1-25: EventInfo

名称 类型 描述

Name String 事件名称。

Time Long 事件发生时间。

OutputData String 事件的输出参数,map格式的字符串。具体结构参见下表OutputData。

EventType String 事件类型。

Identifier String 事件标识符。

表 1-26: OutputData

名称 类型 描述

Key String 参数标识符。

Value Long 参数值。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "NextValid": false, "NextTime": 1516449221253, "List": { "EventInfo": [ { "Name": "testEventInfoName",

86 文档版本:20200417

Page 99: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"Time": "1516517974638", "OutputData": "{\"structArgs\":{\"structchildFLOATf71c20e\":1.23,\"structchildINT6b6b626\":3,\"structchildDATE663436a\":\"1516517966152\",\"structchildDOUBLE08d0f74\":1.23,\"structchildTEXTdc764f9\":\"07b68264b0ba42c18e5f\",\"structchildBOOLd260729\":0,\"structchildENUMbe62590\":1},\"enumArgs\":0,\"boolArgs\":0,\"floatArgs\":2.3,\"dateArgs\":\"1516517966152\",\"intArgs\":1,\"doubleArgs\":2.3,\"textArgs\":\"dV56zbkzjBjw1Ti1dA52\"}", "EventType": "info", "Identifier": "testEventInfo" }, { "Name": "testEventInfoName", "Time": "1516449221254", "OutputData": "{\"structArgs\":{\"structchildFLOATf71c20e\":1.23,\"structchildINT6b6b626\":3,\"structchildDATE663436a\":\"1516449212507\",\"structchildDOUBLE08d0f74\":1.23,\"structchildTEXTdc764f9\":\"a1f3583dde3944289639\",\"structchildBOOLd260729\":0,\"structchildENUMbe62590\":1},\"enumArgs\":0,\"boolArgs\":0,\"floatArgs\":2.3,\"dateArgs\":\"1516449212507\",\"intArgs\":1,\"doubleArgs\":2.3,\"textArgs\":\"1z4XNBvvA7eZw8XViaJp\"}", "EventType": "info", "Identifier": "testEventInfo" } ] } }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryDeviceEventDataResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <NextValid>false</NextValid> <NextTime>1516449221253</NextTime> <List> <EventInfo> <Name>testEventInfoName</Name> <Time>1516517974638</Time> <OutputData>{"structArgs":{"structchildFLOATf71c20e":1.23,"structchildINT6b6b626":3,"structchildDATE663436a":"1516517966152","structchildDOUBLE08d0f74":1.23,"structchildTEXTdc764f9":"07b68264b0ba42c18e5f","structchildBOOLd260729":0,"structchildENUMbe62590":1},"enumArgs":0,"boolArgs":0,"floatArgs":2.3,"dateArgs":"1516517966152","intArgs":1,"doubleArgs":2.3,"textArgs":"dV56zbkzjBjw1Ti1dA52"}</OutputData> <EventType>info</EventType> <Identifier>testEventInfo</Identifier> </EventInfo> <EventInfo> <Name>testEventInfoName</Name> <Time>1516449221254</Time> <OutputData>{"structArgs":{"structchildFLOATf71c20e":1.23,"structchildINT6b6b626":3,"structchildDATE663436a":"1516449212507","structchildDOUBLE08d0f74":1.23,"structchildTEXTdc764f9":"a1f3583dde3944289639","structchildBOOLd260729":0,"structchildENUMbe62590":1},"enumArgs":0,"boolArgs":0,"floatArgs":2.3,"dateArgs":"1516449212507","intArgs":1,"doubleArgs":2.3,"textArgs":"1z4XNBvvA7eZw8XViaJp"}</OutputData> <EventType>info</EventType> <Identifier>testEventInfo</Identifier> </EventInfo> </List> </Data>

文档版本:20200417 87

Page 100: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryDeviceEventDataResponse>

1.1.2.7.17 QueryDevicePropertyData调用该接口查询指定设备的属性记录。

限制说明

仅能查询最近30天内的属性数据。

说明:

数据存储时间从属性时间戳表示的时间当日开始计算。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDevicePropertyData。

IotId String 否 要查询的设备ID,设备的唯一标识符。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 指定要查询的设备隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 指定要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

88 文档版本:20200417

Page 101: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Identifier String 是 要查询的属性标识符。

设备的属性Identifier,可在控制台中设备所

属的产品的功能定义中查看。若设备有多个属

性,您可以多次调用该接口进行查询,一次输

入一个Identifier。

StartTime Long 是 要查询的属性记录的开始时间。取值为毫秒值时间戳。

说明:只能查询最近30天内的属性数据记录。

EndTime Long 是 要查询的属性记录的结束时间。取值为毫秒值时间戳。

PageSize Integer 是 返回结果中每页显示的记录数。数量限制:每页最多可显示50条。

Asc Integer 是 返回结果中属性记录的排序方式,取值:

0:倒序。

1:正序。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的设备属性记录。详情参见下表Data。

文档版本:20200417 89

Page 102: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-27: Data

名称 类型 描述

List List<PropertyList>

属性集合。每个元素代表一个属性。元素的结构参见下表PropertyInfo。

说明:返回的属性信息按照属性生成时间倒序排列。

NextValid Boolean 是否有下一页属性记录。true表示有,false表示没有。

返回NextValid为true时,可以将NextTime的值作为下次

查询的StartTime,查询下一页数据。

NextTime Long 下一页面中的属性记录的起始时间。

调用本接口查询下一页属性记录时,该值可作为入参

StartTime的值。

表 1-28: PropertyInfo

名称 类型 描述

Value String 属性值。

Time Long 属性修改时间。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "NextValid": true, "NextTime": 1516541821599, "List": { "PropertyInfo": [ { "Value": "32", "Time": 1516541894876 }, { "Value": "2", "Time": 1516541885630 },

90 文档版本:20200417

Page 103: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

{ "Value": "95", "Time": 1516541875947 }, { "Value": "14", "Time": 1516541830905 }, { "Value": "78", "Time": 1516541821600 } ] } }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryDevicePropertyDataResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <NextValid>true</NextValid> <NextTime>1516541821599</NextTime> <List> <PropertyInfo> <Value>32</Value> <Time>1516541894876</Time> </PropertyInfo> <PropertyInfo> <Value>2</Value> <Time>1516541885630</Time> </PropertyInfo> <PropertyInfo> <Value>95</Value> <Time>1516541875947</Time> </PropertyInfo> <PropertyInfo> <Value>14</Value> <Time>1516541830905</Time> </PropertyInfo> <PropertyInfo> <Value>78</Value> <Time>1516541821600</Time> </PropertyInfo> </List> </Data></QueryDevicePropertyDataResponse>

1.1.2.7.18 QueryDevicePropertiesData调用该接口批量查询指定设备的属性上报数据。

限制说明

• 一次调用最多可查询10个属性的历史数据。

• 每个属性最多返回100条数据。

文档版本:20200417 91

Page 104: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 仅能查询最近30天内的属性数据。

说明:

数据存储时间从属性生成当日开始计算。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QueryDevicePropertiesData。

ProductKey String 是 设备所属的产品Key。

DeviceName String 是 设备名称。

Identifiers List 是 属性的标识符列表。设备的属性Identifier信息,可在控制台中,设备所属的产品的功能定义中查看。

不可输入重复的属性Identifier。

StartTime Long 是 属性记录的开始时间。取值为13位毫秒值时间戳。

说明:只能查询最近30天内的数据。

EndTime Long 是 属性记录的结束时间。取值为13位毫秒值时间戳。

PageSize Integer 是 单个属性可返回的数据记录数量。最大值为100。

任意一个属性返回的数据记录数量不超过该值。

Asc Integer 是 返回结果中,属性记录按时间排序的方式。取值:

• 0:倒序。倒序查询时,StartTime必须大于EndTime。

• 1:正序。正序查询时,StartTime必须小于EndTime。

IotInstanceId String 否 仅独享实例需传入实例ID;公共实例不传入此参数。

公共请求参数 - 是 请参见公共参数。

92 文档版本:20200417

Page 105: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

NextValid Boolean 是否有下一页属性记录。true表示有,false表示没有。

返回NextValid为true时,可以将NextTime的值作为下次

查询的StartTime,继续查询本次查询不显示的数据。

NextTime Long 下一页属性记录的起始时间。

可以将NextTime的值作为下次查询的StartTime,继续查

询本次查询不显示的数据。

Code String 调用失败时,返回的错误码。请参见错误码。

PropertyDataInfos

List 调用成功时,返回的属性信息列表。具体信息,请参见下表PropertyDataInfo。

表 1-29: PropertyDataInfo

名称 类型 描述

Identifier String 属性的标识符。

List List 属性数据列表。具体信息,请参见下表PropertyInfo。

表 1-30: PropertyInfo

名称 类型 描述

Time Long 属性上报时间。

Value String 属性值。

示例

请求示例

返回示例

• JSON格式

{ "NextValid": true,

文档版本:20200417 93

Page 106: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"NextTime": 1540115949818, "RequestId": "75649FF8-36CD-421B-96C6-35B725FE823B", "Success": true "PropertyDataInfos": { "PropertyDataInfo": [{ "List":{ "PropertyInfo": [{ "Value": "166.0", "Time": 1540116010518 }, { "Value": "166.0", "Time": 1540116009906 }, { "Value": "134.0", "Time": 1540115951051 }, { "Value": "133.0", "Time": 1540115950431 }, { "Value": "133.0", "Time": 1540115949819 } ] }, "Identifier":"Circle"

}, { "List": { "PropertyInfo": [{ "Value": "99.0", "Time": 1540116010314 }, { "Value": "99.0", "Time": 1540116009702 }, { "Value": "98.0", "Time": 1540116009090 }, { "Value": "51.0", "Time": 1540115950844 }, { "Value": "50.0", "Time": 154011595228 } ] }, "Identifier": "Weight" } ] },

94 文档版本:20200417

Page 107: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDevicePropertiesData> <NextValid>true</NextValid> <NextTime>1540115949818</NextTime> <RequestId>75649FF8-36CD-421B-96C6-35B725FE823B</RequestId> <PropertyDataInfos> <PropertyDataInfo> <List> <PropertyInfo> <Value>166.0</Value> <Time>1540116010518</Time> </PropertyInfo> <PropertyInfo> <Value>166.0</Value> <Time>1540116009906</Time> </PropertyInfo> <PropertyInfo> <Value>134.0</Value> <Time>1540115951051</Time> </PropertyInfo> <PropertyInfo> <Value>133.0</Value> <Time>1540115950431</Time> </PropertyInfo> <PropertyInfo> <Value>133.0</Value> <Time>1540115949819</Time> </PropertyInfo> </List> <Identifier>Circle</Identifier> </PropertyDataInfo> <PropertyDataInfo> <List> <PropertyInfo> <Value>99.0</Value> <Time>1540116010314</Time> </PropertyInfo> <PropertyInfo> <Value>99.0</Value> <Time>1540116009702</Time> </PropertyInfo> <PropertyInfo> <Value>98.0</Value> <Time>1540116009090</Time> </PropertyInfo> <PropertyInfo> <Value>51.0</Value> <Time>1540115950844</Time> </PropertyInfo> <PropertyInfo> <Value>50.0</Value> <Time>1540115950228</Time> </PropertyInfo> </List> <Identifier>Weight</Identifier> </PropertyDataInfo> </PropertyDataInfos> <Success>true</Success>

文档版本:20200417 95

Page 108: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryDevicePropertiesData>

1.1.2.7.19 QueryDeviceServiceData调用该接口查询指定设备的服务调用记录。

限制说明

仅能查询最近30天内的服务数据。

说明:

数据存储时间从调用服务当日开始计算。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceServiceData。

IotId String 否 要查询服务调用记录的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey&DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询服务调用记录的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要查询服务调用记录的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

Identifier String 是 要查询的服务标识符。设备的服务Identifier。可在控制台中设备所属的产品的功能定义中查看。

96 文档版本:20200417

Page 109: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

StartTime Long 是 要查询的服务调用记录的开始时间。取值为13位的毫秒值时间戳。

说明:只能查询最近30天内的数据。

EndTime Long 是 要查询的服务调用记录的结束时间。取值为13位的毫秒值时间戳。

PageSize Integer 否 返回结果中每页显示的记录数。数量限制:每页最多可显示50条。

Asc Integer 否 返回结果中服务调用记录的排序方式,取值:

0:倒序。

1:正序。

默认值是1(正序)。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的设备服务调用记录。详情参见下表Data。

表 1-31: Data

名称 类型 描述

List List<ServiceInfo> 服务记调用录集合。每个元素代表一个服务执调用录。元素的结构参见下表ServiceInfo。

文档版本:20200417 97

Page 110: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

NextValid Boolean 表示是否有下一页服务调用记录。

• true:有• false:没有

NextTime Long 下一页面中的服务调用记录的起始时间。

调用本接口查询下一页服务调用记录时,该值可作为请求

StartTime的值。

表 1-32: ServiceInfo

名称 类型 描述

Name String 服务名称。

Time Long 调用服务的时间。

OutputData String 服务的输出参数,map格式的字符串,结构为 key:value。

InputData String 服务的输入参数,map格式的字符串,结构为 key:value。

Identifier String 服务标识符。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "NextValid": true, "NextTime": 1517315865197, "List": { "ServiceInfo": [ { "Name": "set", "Time": 1517315865198, "OutputData": "{\"code\":200,\"data\":{},\"id\":\"100686\",\"message\":\"success\",\"version\":\"1.0\"}", "InputData": "{\"LightAdjustLevel\":123}", "Identifier": "set" } ] } }

98 文档版本:20200417

Page 111: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryDeviceServiceDataResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <NextValid>true</NextValid> <NextTime>1517315865197</NextTime> <List> <ServiceInfo> <Name>set</Name> <Time>1517315865198</Time> <OutputData>{"code":200,"data":{},"id":"100686","message":"success","version":"1.0"}</OutputData> <InputData>{"LightAdjustLevel":123}</InputData> <Identifier>set</Identifier> </ServiceInfo> </List> </Data></QueryDeviceServiceDataResponse>

1.1.2.7.20 InvokeThingService调用该接口在一个设备上调用指定服务。

限制说明

如果同步调用服务,最大超时时间为5秒。若5秒内服务器未收到回复,则返回超时错误;如果异步调

用服务,则无最大超时时间限制。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:InvokeThingService。

IotId String 否 要调用服务的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,和ProductKey与DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。不能传入空参数。

文档版本:20200417 99

Page 112: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ProductKey String 否 要调用服务的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要调用服务的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

Identifier String 是 服务的标识符。设备的服务Identifier,可在控制台中设备所属的产品的功能定义中查看。有关功能定义说明,请参见 《用户指南》 中设备管理 > 物模型 > 单个添加物模型。

Args String 是 要启用服务的入参信息,数据格式为JSON

String,如, Args={"param1":1}。

若此参数为空时,需传入 Args={} 。

Args详情参见下表Args。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-33: Args

名称 类型 描述

key String 输入参数的标识符。您在创建该服务时,设置的输入参数

的标识符。

您可以在控制台设备所属的产品的功能定义页面,从该产

品的物模型中查看,或单击该服务对应的编辑按钮,然后

查看您设置的输入参数的信息。

value Object 指定参数值。该值须在您设置的输入参数的取值范围内 。

100 文档版本:20200417

Page 113: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情请见下表Data。

表 1-34: Data

名称 类型 描述

Result String 同步调用服务,返回的调用结果。

异步调用服务,不返回此参数。

MessageId String 云端向设备下发服务调用的消息ID。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data":{" "Result": "...." "MessageId": "abcabc123" }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><InvokeThingServiceResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <Result>...</Result> <MessageId>abcabc123</MessageId> </Data>

文档版本:20200417 101

Page 114: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</InvokeThingServiceResponse>

1.1.2.7.21 InvokeThingsService调用该接口批量调用设备服务。

使用限制

目前只支持异步调用该接口。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:InvokeThingsService。

ProductKey String 是 要调用服务的设备所隶属的产品Key。

DeviceNames

List<String> 是 要调用服务的设备的名称列表。最多支持100个

设备。

Identifier String 是 服务的标识符。

设备的服务Identifier,可在控制台中设备所

属产品的功能定义中查看。有关功能定义说

明,请参见 《用户指南》 中设备管理 > 物模型

> 单个添加物模型。

Args String 是 要启用服务的入参信息,数据格式为JSON

String,如, Args={"param1":1}。

若此参数为空时,需传入 Args={} 。

Args详情参见下表Args。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

102 文档版本:20200417

Page 115: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-35: Args

名称 类型 描述

key String 输入参数的标识符。您在创建该服务时,设置的输入参数

的标识符。

您可以在控制台设备所属产品的功能定义页面,从该产品

的物模型中查看,或单击该服务对应的编辑按钮,然后查

看您设置的输入参数的信息。

value Object 指定参数值。该值须在您设置的输入参数的取值范围内 。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON 格式

{ "RequestId": "059C3274-6197-4BEC-95E4-49A076330E57", "Success": true}

• XML 格式

<?xml version='1.0' encoding='utf-8'?><InvokeThingsServiceResponse> <RequestId>"059C3274-6197-4BEC-95E4-49A076330E57</RequestId> <Success>true</Success>

文档版本:20200417 103

Page 116: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</InvokeThingsServiceResponse>

1.1.2.7.22 GetGatewayBySubDevice调用该接口,根据挂载的子设备信息,查询对应的网关设备信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:GetGatewayBySubDevice。

IotId String 否 子设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey与DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 子设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 子设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

104 文档版本:20200417

Page 117: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的网关设备的详细信息。详情请参见下表DeviceDetailInfo。

表 1-36: DeviceDetailInfo

名称 类型 描述

ProductKey String 网关设备隶属的产品Key。

ProductName String 网关设备隶属的产品名称。

DeviceName String 网关设备名称。

DeviceSecret String 网关设备密钥。

IotId String IoT平台为该网关设备颁发的ID,作为该设备的唯一标识符。

GmtCreate String 网关设备的创建时间,GMT时间。

GmtActive String 网关设备的激活时间,GMT时间。

GmtOnline String 网关设备最近一次上线的时间,GMT时间。

UtcCreate String 网关设备的创建时间,UTC时间。

UtcActive String 网关设备的激活时间,UTC时间。

UtcOnline String 网关设备最近一次上线的时间,UTC时间。

Status String 网关设备状态。取值:

ONLINE:设备在线。

OFFLINE:设备离线。

UNACTIVE:设备未激活。

DISABLE:设备已禁用。

FirmwareVersion

String 网关设备的固件版本号。

IpAddress String 网关设备的IP地址。

NodeType Integer 节点类型,取值为1,表示该设备为网关设备。

Region String 网关设备所在地域(与控制台上的地域对应)。

文档版本:20200417 105

Page 118: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{"RequestId": "F227A41E-8A0F-4829-A1B1-727619DB58A3", "Data": { "Status": "UNACTIVE", "ProductName": "TEST", "DeviceSecret": "nICOJkFJnG***********TWnvXHydEjX", "UtcOnline": "", "IotId": "9a1MTdk9brqQ2bhdG4OY001094fd00", "GmtCreate": "2018-08-07 15:54:15", "UtcCreate": "2018-08-07T07:54:15.000Z", "UtcActive": "", "GmtActive": "", "NodeType": 1, "Region": "cn-shanghai", "GmtOnline": "", "ProductKey": "a15tzTmkWZ2", "DeviceName": "d896e0ff000105bb" "IpAddress": "10.0.0.1" "FirmwareVersion": "1.2.3" },"Success": true}

• XML格式

<?xml version='1.0' encoding='utf-8'?><GetGatewayBySubDeviceResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <Status>UNACTIVE</Status> <ProductName>TEST</ProductName> <DeviceSecret>nICOJkFJnG***********TWnvXHydEjX</DeviceSecret> <UtcOnline></UtcOnline> <IotId>SR8FiTu1R9tlUR2V1bmi0010******</IotId> <GmtCreate>2018-08-07 15:54:15</GmtCreate> <UtcCreate>2018-08-07T07:54:15.000Z</GmtOnline> <UtcActive></UtcActive> <GmtActive></GmtActive> <NodeType>1</NodeType> <Region>cn-shanghai</Region> <GmtOnline></GmtOnline> <ProductKey>a15tzTmkWZ2</ProductKey> <DeviceName>TEST</DeviceName> <IpAddress>10.0.0.1</IpAddress> <FirmwareVersion>1.2.3</FirmwareVersion> </Data>

106 文档版本:20200417

Page 119: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</GetGatewayBySubDeviceResponse>

1.1.2.7.23 QueryDevicePropertyStatus调用该接口查询指定设备的属性快照。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDevicePropertyStatus。

IotId String 否 要查询的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey & DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId String 否 仅独享实例需传入实例ID;公共实例不传入此参数。

公共请求参数 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

文档版本:20200417 107

Page 120: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情参见下表Data。

表 1-37: Data

名称 类型 描述

List List 返回的属性集合信息。详情参见下表PropertyStatusInfo。

表 1-38: PropertyStatusInfo

名称 类型 描述

Identifier String 属性标识符。

Name String 属性名称。

DataType String 属性格式类型,取值:

int:整型。

float:单精度浮点型。

double:双精度浮点型。

enum:枚举型。

bool:布尔型。

text:字符型。

date:时间型(String类型的UTC时间戳,单位是毫

秒)。

array:数组型。

struct:结构体类型。

Time String 属性修改的时间,单位是毫秒。

Value String 属性值。

Unit String 属性单位。

108 文档版本:20200417

Page 121: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "List": { "PropertyStatusInfo": [ { "Name": "doublePropertyName", "Value": "50.0", "Time": "1517553572362", "DataType": "double", "Identifier": "doubleProperty", "Unit": "C" } ] } }

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryDevicePropertyStatusResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <List> <PropertyStatusInfo> <Time>1517553572362</Time> <Name>doublePropertyName</Name> <DataType>double</DataType> <Identifier>doubleProperty</Identifier> <Value>50.0</Value> <Unit>C</Unit> </PropertyStatusInfo> </List> </Data></QueryDevicePropertyStatusResponse>

1.1.2.7.24 SetDeviceProperty调用该接口为指定设备设置属性值。

返回结果说明

因为云端下发属性设置命令和设备收到并执行该命令是异步的,所以调用该接口时,返回的成功结果

只表示云端下发属性设置的请求成功,不能保证设备端收到并执行了该请求。需设备端SDK成功响应

云端设置设备属性值的请求,设备属性值才能真正设置成功。

文档版本:20200417 109

Page 122: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:SetDeviceProperty。

IotId String 否 要设置属性值的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要设置属性值的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要设置属性值的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

Items String 是 要设置的属性信息,数据格式为 JSON String。

属性组成为属性标识符key:属性值value,多个

属性用英文逗号隔开。

例如,设置智能灯的如下两个属性:

• 标识符为Switch的开关属性,数据类型为Bool,设置值为1(开);

• 标识符为Color的灯颜色属性,数据类型为String,设置值为blue。

那么,Items={"Switch":1,"Color":"blue"}。

属性标识符key和属性值value的取值说明,请参见下表Items。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

110 文档版本:20200417

Page 123: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-39: Items

名称 类型 描述

key String 要设置的属性的标识符(identifier)。设备的属性

Identifier,可在控制台中设备所属的产品的功能定义中查

看。

说明:设置的属性必需是读写型。如果您指定了一个只读型的属性,设置将会失败。

value Obejct 属性值。取值需和您定义的属性的数据类型和取值范围保持一致。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情请参见下表Data。

表 1-40: Data

名称 类型 描述

MessageId String 云端给设备下发属性设置的消息ID。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "MessageId":"abcabc123"

文档版本:20200417 111

Page 124: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

} }

• XML格式

<?xml version='1.0' encoding='utf-8'?><SetDevicePropertyResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <MessageId>abcabc123</MessageId> </Data></SetDevicePropertyResponse>

1.1.2.7.25 SetDevicesProperty调用该接口批量设置设备属性值。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:SetDevicesProperty。

ProductKey String 是 要设置属性值的设备所隶属的产品Key。

DeviceNames

List<String> 是 要设置属性值的设备名称列表。目前,最多支

持100个设备。

Items String 是

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

112 文档版本:20200417

Page 125: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回示例

• JSON 格式

{ "RequestId": "2E19BDAF-0FD0-4608-9F41-82D230CFEE38", "Success": true}

• XML 格式

<?xml version='1.0' encoding='utf-8'?><SetDevicesPropertyResponse> <RequestId>"2E19BDAF-0FD0-4608-9F41-82D230CFEE3</RequestId> <Success>true</Success></SetDevicesPropertyResponse>

1.1.2.7.26 QueryDeviceProp调用该接口查询指定设备的标签列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceProp。

IotId String 否 物联网平台为该设备颁发的设备ID,作为该设备的唯一标识符。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

文档版本:20200417 113

Page 126: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Props String 调用成功时,返回的设备标签信息列表。

示例

请求示例

返回示例

• JSON 格式

{ "RequestId": "D8CEF5E7-1484-4164-A242-C06BA3A54E0F", "Props": "{\"coordinate\":\"104.07086:30.549169\"}", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDevicePropResponse> <RequestId>D8CEF5E7-1484-4164-A242-C06BA3A54E0F</RequestId> <Props> <coordinate>104.07086:30.549169</coordinate> </Props> <Success>true</Success></QueryDevicePropResponse>

1.1.2.7.27 SaveDeviceProp调用该接口为指定设备设置标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:SaveDeviceProp。

114 文档版本:20200417

Page 127: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ProductKey String 否 要创建标签的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要创建标签的设备名称。

说明:如果传入该参数,需同时传入ProductKey。

IotId String 否 设备ID,物联网平台为设备颁发的唯一标识。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey & DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

Props String 是 要设置的设备标签。设备标签是JSON格式,

Props是对应的String格式。

每个标签由标签key和value组

成,key和value均不能为空。多个标签用英文

逗号隔开,如,Props={"color":"red","room

":"001"}。

标签的key和value的取值说明,请参见下表

Prop。

说明:

• Props的总大小不超过5K。• 单个设备的设备标签总数不超过100个。• 单次修改或新增的设备标签数不超过100

个。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

文档版本:20200417 115

Page 128: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

公共请求参数 - 是 请参见公共参数。

表 1-41: Prop

名称 类型 是否必需 描述

key String 是 设置标签键值。标签键值可包含英文字母,数

字和点号(.),长度在2-30字符之间。

如果设置的键值已存在,则将覆盖之前的标签

值。

如果设置的键值不存在,则新增标签。

value Object 是 标签值。可包含中文、英文字母、数字、下划线(_)、连字符(-)和点号(.)。长度不可超过128字符。一个中文汉字算2字符。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true}

• XML格式

<?xml version='1.0' encoding='utf-8'?><SaveDevicePropResponse>

116 文档版本:20200417

Page 129: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></SaveDevicePropResponse>

1.1.2.7.28 DeleteDeviceProp调用该接口删除设备下的指定标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteDeviceProp。

IotId String 否 要删除标签的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey & DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要删除标签的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要删除标签的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

PropKey String 是 要删除的设备标签键值(Key)。

说明:物联网平台在目标设备的标签中检索您提供的Key值,并删除与之对应的标签。如果目标设备的标签中没有与您提供的Key值对应的记录,则不执行任何操作。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

文档版本:20200417 117

Page 130: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true}

• XML格式

<?xml version='1.0' encoding='utf-8'?><DeleteDevicePropResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success></DeleteDevicePropResponse>

1.1.2.7.29 QueryDeviceByTags调用该接口通过标签查询设备。

限制说明

一次调用,最多可输入10个标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值 QueryDeviceByTags。

PageSize Integer 否 指定返回结果中每页显示的记录数量,最大值是50。默认值是10。

CurrentPage Integer 否 指定从返回结果中的第几页开始显示。默认值是1。

118 文档版本:20200417

Page 131: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Tag List<Tag> 是 设备标签。数量限制:可输入最多10个标签。

Tag 包括TagKey和TagValue,分别对应标签

的key和value。

支持只传入TagKey进行查询。

详情请参见下表 Tag。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 公共请求参数,请参见公共参数。

表 1-42: Tag

名称 类型 是否必需 描述

TagKey String 是 设备标签的key。

TagValue String 否 设备标签的value。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

PageCount Integer 总页数。

PageSize Integer 每页显示的记录数。

Page Integer 当前页面号。

Total Integer 总记录数。

Data Data 调用成功时,返回的设备信息列表。详情参见下表SimpleDeviceInfo。

文档版本:20200417 119

Page 132: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-43: SimpleDeviceInfo

名称 类型 描述

ProductName String 产品名称。

ProductKey String 产品Key。

DeviceName String 设备名称。

IotId String 物联网平台为该设备颁发的ID,作为该设备的唯一标识符。

示例

请求示例

返回示例

• JSON格式

{ "PageCount": 1, "Data": { "SimpleDeviceInfo": [ { "DeviceName": "1102jichu02", "ProductKey": "a1SM5S1shy1", "IotId": "GookTiUcwqRbHosp9Ta10017d3a00", "ProductName": "TEST" } ] }, "PageSize": 10, "Page": 1, "RequestId": "2B5091E4-32D5-4884-A5B2-2E8E713D84AF", "Success": true, "Total": 1}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceByTags> <PageCount>1</PageCount> <Data> <SimpleDeviceInfo> <DeviceName>1102jichu02</DeviceName> <ProductKey>a1SM5S1shy1</ProductKey> <IotId>GookTiUcwqRbHosp9Ta10017d3a00</IotId> <ProductName>TEST</ProductName> </SimpleDeviceInfo> </Data> <PageSize>10</PageSize> <Page>1</Page> <RequestId>2B5091E4-32D5-4884-A5B2-2E8E713D84AF</RequestId> <Success>true</Success> <Total>1</Total>

120 文档版本:20200417

Page 133: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryDeviceByTags>

1.1.2.7.30 GetThingTopo调用该接口查询指定设备的拓扑关系。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:GetThingTopo。

IotId String 否 要查询的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

PageSize Integer 是 返回结果中每页显示的记录数量。数量限制:每页最多可显示50条记录。

PageNo Integer 是 从返回结果中的第几页开始显示。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

文档版本:20200417 121

Page 134: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的设备信息集合。详情参见下表DeviceDataInfo。

表 1-44: DeviceDataInfo

名称 类型 描述

PageCount Integer 总页数。

PageSize Integer 每页显示的记录数。

List List 设备信息集合。每个元素的结构参见下表DeviceInfo。

CurrentPage Integer 当前页面号。

Total Integer 总记录数。

表 1-45: DeviceInfo

名称 类型 描述

IotId String 设备的ID。

ProductKey String 设备所隶属的产品Key。

DeviceName String 设备名称。

DeviceSecret String 设备密钥。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true "Data": { "PageCount": 1, "PageSize": 10, "List": { "deviceInfo": [

122 文档版本:20200417

Page 135: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

{ "DeviceName": "device1", "ProductKey": "al*********", "DeviceSecret":"abc******" "IotId": "SR8FiTu1R9tlUR2V1bmi0010*****" } ] }, "CurrentPage": 1, "Total": 1 },

}

• XML格式

<?xml version='1.0' encoding='UTF-8'?><GetThingTopoResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <PageCount>1</PageCount> <PageSize>10</PageSize> <List> <DeviceInfo> <DeviceName>device1</DeviceName> <ProductKey>al*********</ProductKey> <DeviceSecret>abc******</DeviceSecret> <IotId>SR8FiTu1R9tlUR2V1bmi0010*****</IotId> </DeviceInfo> </List> <CurrentPage>1</CurrentPage> <Total>1</Total> </Data></GetThingTopoResponse>

1.1.2.7.31 NotifyAddThingTopo调用该接口通知网关设备增加拓扑关系。

使用说明

• 返回的成功结果只表示添加拓扑关系的指令成功下发给网关,但并不表示网关成功添加拓扑关

系。

• 开发网关设备端时,需订阅通知添加拓扑关系消息的Topic。具体Topic和消息格式,请参见 《用

户指南》 中设备管理 > Alink协议 > 管理拓扑关系通知网关添加设备拓扑关系。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:NotifyAddThingTopo。

文档版本:20200417 123

Page 136: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

GwIotId String 否 要通知的网关设备ID,即网关类型设备的IotId。

说明:如果传入该参数,则无需传入GwProductKey和GwDeviceName。GwIotId作为设备唯一标识符,与GwProductKey和GwDeviceName组合是一一对应的关系。如果您同时传入GwIotId和GwProductKey与GwDeviceName组合,则以GwIotId为准。

GwProductKey

String 否 要通知的网关设备所隶属的产品Key,即网关类型产品

的ProductKey。

说明:如果传入该参数,需同时传入GwDeviceName。

GwDeviceName

String 否 要通知的网关设备的名称,即网关类型设备的

DeviceName。

说明:如果传入该参数,需同时传入GwProductKey。

DeviceListStr

List 是 要挂载在目标网关设备上的子设备数组,为JSON字符串形式。具体结构参见下表DeviceList。

IotInstanceId

String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数

- 是 请参见公共参数。

表 1-46: DeviceList

名称 类型 是否必需 描述

ProductKey String 否 子设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

124 文档版本:20200417

Page 137: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceName String 否 子设备名称。

说明:如果传入该参数,需同时传入ProductKey。

IotId String 否 子设备ID,物联网平台颁发给设备的唯一标

识。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey & DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情请见下表Data。

表 1-47: Data

名称 类型 描述

MessageId String 云端向网关设备下发增加拓扑关系的消息ID。

示例

请求示例

返回示例

文档版本:20200417 125

Page 138: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "RequestId":"419A3FC1-B517-4958-9414-5546765FA51F", "Success": true, "Data":{ "MessageId": "abcabc123" }}

• XML格式

<?xml version='1.0' encoding='UTF-8'?><NotifyAddThingTopoResponse> <RequestId>419A3FC1-B517-4958-9414-5546765FA51F</RequestId> <Success>true</Success> <Data> <MessageId>abcabc123</MessageId> </Data></NotifyAddThingTopoResponse>

1.1.2.7.32 RemoveThingTopo调用该接口移除网关与子设备的拓扑关系。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:RemoveThingTopo。

IotId String 否 要删除拓扑关系的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要删除拓扑关系的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

126 文档版本:20200417

Page 139: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceName String 否 要删除拓扑关系的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Boolean 删除拓扑关系的结果。true表示删除成功,false表示删除失败。

示例

请求示例

返回示例

• JSON格式

{ "Data": true, "RequestId": "098BEEF4-58F4-4181-A891-5D37DB6C4C3B", "Success": true}

• XML格式

<?xml version='1.0' encoding='UTF-8'?><RemoveThingTopoResponse> <RequestId>098BEEF4-58F4-4181-A891-5D37DB6C4C</RequestId> <Success>true</Success> <Data>true</Data>

文档版本:20200417 127

Page 140: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</RemoveThingTopoResponse>

1.1.2.7.33 QueryDeviceStatistics调用该接口查询设备统计数据。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceStatistics。

ProductKey String 否 要查询的设备所隶属的产品Key。

• 传入产品Key,将返回该产品下的设备统计数据。

• 不传入该参数,则返回账号下所有设备统计数据。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的设备统计信息。详情参见下表。

表 1-48: StatisticsInfo

名称 类型 描述

deviceCount Long 设备总数。

onlineCount Long 在线的设备数量。

activeCount Long 已激活的设备数量。

128 文档版本:20200417

Page 141: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data": { "deviceCount": 100, "onlineCount": 10, "activeCount": 50 }}

• XML格式

<?xml version='1.0' encoding='utf-8'?><QueryDeviceStatisticsResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <deviceCount>100</deviceCount> <onlineCount>10</onlineCount> <activeCount>50</activeCount> </Data></QueryDeviceStatisticsResponse>

1.1.2.7.34 SetDeviceDesiredProperty调用该接口为指定设备批量设置期望属性值。

限制说明

• 只读属性不支持设置期望属性值。

• 一次调用最多可设置10个期望属性值。

• 设备创建后,期望属性值的版本(Version)为0。首次设置期望属性值时,如果指定Version参

数,则需指定Version值为0。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:SetDeviceDesiredProperty。

文档版本:20200417 129

Page 142: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

IotId String 否 要设置期望属性值的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey和DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要设置期望属性值的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

DeviceName String 否 要设置期望属性值的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

Items String 是 要设置的期望属性值,组成为key:value,数据

格式为 JSON String,如{"Power":1}。

详情参见下表Items。

说明:最多可输入10个期望属性值。

Versions String 否 当前期望属性值版本,组成为key:value,数据

格式为 JSON String,如{"Power":2}。

详情参见下表Versions。

说明:如果传入的版本号与当前版本不符,服务器将拒绝此次请求。若您不确定当前期望值的版本号,可以不传入版本号,但仍需传入有效的JSON,即传入{}。

130 文档版本:20200417

Page 143: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-49: Items

名称 类型 描述

key String 取值为属性的标识符(identifier)。可在控制台中,设备

所属产品的功能定义中查看属性的identifier。

说明:

• 指定属性必须是读写型。如果您指定了一个只读型的属性,设置将会失败。

• 一次调用中,key的取值(即属性的identifier)不能重复。

value Object 要设置的期望属性值。取值需符合您为该属性定义的数据

类型和取值范围。

说明:若属性值设置为null,则表示清空期望属性值。

表 1-50: Versions

名称 类型 描述

key String 取值为属性的标识符(identifier)。可在控制台中,设备所属产品的功能定义中查看属性的identifier。

说明:一次调用中,key的取值(即属性的identifier)不能重复。

文档版本:20200417 131

Page 144: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

value Long 当前期望属性值的版本号。

首次设置期望属性值时,指定该参数值为0。首次设置期望

属性值后,期望值版本号为1。以后每次设置期望值后,物

联网平台自动将期望值版本加1(即第二次设置期望属性

值时,指定该参数值为1。设置成功后,版本号自动变为2

;第三次设置时,指定该参数值为2。设置成功后,版本号

自动变为3;以此类推)。

说明:若传入的版本号与当前版本号不符,请求将失败。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情请参见下表Data。

表 1-51: Data

名称 类型 描述

MessageId String 云端下发给设备的设置期望属性值的消息ID。

Version String 本次设置期望属性值后,期望属性值的当前版本号。

示例

请求示例

返回示例

• JSON格式

{ "Data": { "MessageId": "300511751",

132 文档版本:20200417

Page 145: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"Versions": "{\"Power\":2}" }, "RequestId": "AADE79D2-B328-4FC6-A3E0-34BB23BCA440", "Success": true}

• XML格式

<?xml version='1.0' encoding='utf-8'?><SetDeviceDesiredPropertyResponse> <RequestId>AADE79D2-B328-4FC6-A3E0-34BB23BCA440</RequestId> <Success>true</Success> <Data> <MessageId>300511751</MessageId> <Versions>{"Power":2}</Versions> </Data></SetDeviceDesiredPropertyResponse>

1.1.2.7.35 QueryDeviceDesiredProperty调用该接口查询指定设备的期望属性值。

限制说明

• 只读属性不支持查询期望属性值。

• 一次调用最多能查询10个属性的期望值。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceDesiredProperty。

IotId String 否 要查询的设备ID。

说明:如果传入该参数,则无需传入ProductKey和DeviceName。IotId作为设备唯一标识符,与ProductKey & DeviceName组合是一一对应的关系。如果您同时传入IotId和ProductKey与DeviceName组合,则以IotId为准。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入DeviceName。

文档版本:20200417 133

Page 146: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入ProductKey。

Identifiers List 否 要查询期望值的属性的标识符(identifier)列

表。

设备的属性identifier,可在控制台中,设备所

属产品的功能定义中查看。

说明:

• 单次调用,最多能传入10个identifier。• 不可输入重复的属性identifier。• 若不传入此参数,将返回该设备所有属性

的期望值。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的数据。详情参见下表Data。

表 1-52: Data

名称 类型 描述

List List<DesiredPropertyInfo>

返回的属性信息。详情参见下表DesiredPropertyInfo。

134 文档版本:20200417

Page 147: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-53: DesiredPropertyInfo

名称 类型 描述

Identifier String 属性标识符。

Name String 属性名称。

DataType String 属性数据类型。

Time String 期望属性值的修改时间,单位是毫秒。

Value String 期望属性值。

Unit String 属性单位。

Version Long 当前期望属性值的版本号。

示例

请求示例

返回示例

• JSON 格式

{ "RequestId":"57b144cf-09fc-4916-a272-a62902d5b207", "Success": true, "Data":{ "List":{ "DesiredPropertyInfo":[ { "Name": "WeightName", "Value": "50.0", "Time": "1517553572362", "DataType": "double", "Identifier": "Weight", "Unit": "C", "Version": 10 }, { "Name": "CircleName", "Value": "50.0", "Time": "1517553572362", "DataType": "double", "Identifier": "Circle", "Unit": "C", "Version": 10 } ] } }}

• XML格式

<?xml version='1.0' encoding='utf-8'?>

文档版本:20200417 135

Page 148: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<QueryDeviceDesiredPropertyResponse> <RequestId>57b144cf-09fc-4916-a272-a62902d5b207</RequestId> <Success>true</Success> <Data> <List> <DesiredPropertyInfo> <Time>1517553572362</Time> <Name>doublePropertyName</Name> <DataType>double</DataType> <Identifier>doubleProperty</Identifier> <Value>50.0</Value> <Unit>C</Unit> <Version>10</Version> </DesiredPropertyInfo> <DesiredPropertyInfo> <Time>1517553572362</Time> <Name>CircleName</Name> <DataType>double</DataType> <Identifier>Circle</Identifier> <Value>50.0</Value> <Unit>C</Unit> <Version>10</Version> </DesiredPropertyInfo> </List> </Data></QueryDeviceDesiredPropertyResponse>

1.1.2.7.36 QueryDeviceFileList调用该接口查询指定设备上传到物联网平台的所有文件列表。

限制说明

调用该接口返回的文件信息中,不包括文件下载地址。如需获取文件下载地址,请调

用QueryDeviceFile查询。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceFileList。

IotId String 否 要查询的设备ID,设备唯一标识符。

说明:如果传入该参数,则无需传入 ProductKey和DeviceName。IotId作为设备唯一标识符,和 ProductKey与 DeviceName组合是一一对应的关系。如果您同时传入 IotId和ProductKey与 DeviceName组合,则以IotId为准。不能传入空参数。

136 文档版本:20200417

Page 149: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入 DeviceName。

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入 ProductKey。

PageSize Integer 否 返回结果中每页显示的文件记录数量。最大取值200,默认值是10。

CurrentPage Integer 否 显示返回结果中的第几页。最小取值1,默认值 1。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data List<FileStoreSummary>

调用成功时,返回的文件信息列表。详情参见下表FileStoreSummary。

表 1-54: FileStoreSummary

名称 类型 描述

FileId String 文件标识符。

Name String 文件名。

Size String 文件大小。

UtcCreatedOn String 文件创建时间。

文档版本:20200417 137

Page 150: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{ "PageCount": 1, "Data": { "FileStoreSummary": [ { "Name": "testFile2.txt", "FileId": "xL0G67MBLBDtkR7GCfT******", "UtcCreatedOn": "2019-03-21T08:45:42.000Z", "Size": "102400" }, { "Name": "testFile3.txt", "FileId": "6UCo1SqbqnQEoh9aKqD******", "UtcCreatedOn": "2019-03-21T08:45:42.000Z", "Size": "102400" }, { "Name": "testFile1.txt", "FileId": "IhXXww3Eeu6uzSOSCyu******", "UtcCreatedOn": "2019-03-21T08:45:40.000Z", "Size": "102400" } ] }, "PageSize": 10, "RequestId": "7C7BA526-826D-46AA-A45E-55D21E6D1583", "CurrentPage": 1, "Success": true, "Total": 3}

• XML格式

<?xml version="1.0" encoding="utf-8"?><QueryDeviceFileListResponse> <PageCount>1</PageCount> <Data> <FileStoreSummary> <Name>testFile2.txt</Name> <FileId>xL0G67MBLBDtkR7GCfT******</FileId> <UtcCreatedOn>2019-03-21T08:45:42.000Z</UtcCreatedOn> <Size>102400</Size> </FileStoreSummary> <FileStoreSummary> <Name>testFile3.txt</Name> <FileId>6UCo1SqbqnQEoh9aKqD******</FileId> <UtcCreatedOn>2019-03-21T08:45:42.000Z</UtcCreatedOn> <Size>102400</Size> </FileStoreSummary> <FileStoreSummary> <Name>testFile1.txt</Name> <FileId>IhXXww3Eeu6uzSOSCyu******</FileId> <UtcCreatedOn>2019-03-21T08:45:40.000Z</UtcCreatedOn>

138 文档版本:20200417

Page 151: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<Size>102400</Size> </FileStoreSummary> </Data> <PageSize>10</PageSize> <RequestId>BF06F7FD-B199-4B90-9128-8416F975135E</RequestId> <CurrentPage>1</CurrentPage> <Success>true</Success> <Total>3</Total></QueryDeviceFileListResponse>

1.1.2.7.37 QueryDeviceFile调用该接口查询指定设备上传到物联网平台的指定文件信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceFile。

IotId String 否 要查询的设备ID,设备唯一标识符。

说明:如果传入该参数,则无需传入 ProductKey和DeviceName。IotId作为设备唯一标识符,和 ProductKey与 DeviceName组合是一一对应的关系。如果您同时传入 IotId和ProductKey与 DeviceName组合,则以IotId为准。不能传入空参数。

ProductKey String 否 要查询的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入 DeviceName。

DeviceName String 否 要查询的设备的名称。

说明:如果传入该参数,需同时传入 ProductKey。

FileId String 是 文件标识符。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

文档版本:20200417 139

Page 152: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data Data 调用成功时,返回的文件信息。详情参见下表Data

表 1-55: Data

名称 类型 描述

FileId String 文件标识符。

Name String 文件名。

Size String 文件大小。

UtcCreatedOn String 文件创建时间。

DownloadUrl String 文件下载URL。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "93C5276D-5C8A-40D9-BFD6-4BD5B8C1A08F", "Data": { "Name": "testFile3.txt", "DownloadUrl": "http://iotx-file-store.oss-cn-shanghai.aliyuncs.com/device_file/A849E4E5CFF64804A18D9384AC9D****/aGEKIpp5NAGxdP2oo90000****/testFile3.txt?Expires=1553162075&OSSAccessKeyId=LTAIYLScbHiV****&Signature=%2F88xdEFPukJ****%2F8****%2Bdv3io%3D", "FileId": "6UCo1SqbqnQEoh9aKqDQ01****", "UtcCreatedOn": "2019-03-21T08:45:42.000Z", "Size": "102400" }, "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><RequestId>93C5276D-5C8A-40D9-BFD6-4BD5B8C1A08F</RequestId><Data> <Name>testFile3.txt</Name> <DownloadUrl>http://iotx-file-store.oss-cn-shanghai.aliyuncs.com/device_file/A849E4E5CFF64804A18D9384AC9D****/aGEKIpp5NAGxdP2oo90000****/testFile3.txt

140 文档版本:20200417

Page 153: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

?Expires=1553162075&amp;OSSAccessKeyId=LTAIYLScbHiV****&amp;Signature=%2F88xdEFPukJ****%2F8****%2Bdv3io%3D</DownloadUrl> <FileId>6UCo1SqbqnQEoh9aKqDQ01****</FileId> <UtcCreatedOn>2019-03-21T08:45:42.000Z</UtcCreatedOn> <Size>102400</Size></Data><Success>true</Success>

1.1.2.7.38 DeleteDeviceFile调用该接口删除指定设备上传到物联网平台的指定文件。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteDeviceFile。

IotId String 否 文件所属的设备ID,设备唯一标识符。

说明:如果传入该参数,则无需传入 ProductKey和DeviceName。IotId作为设备唯一标识符,和 ProductKey与 DeviceName组合是一一对应的关系。如果您同时传入 IotId和ProductKey与 DeviceName组合,则以IotId为准。不能传入空参数。

ProductKey String 否 文件所属的设备所隶属的产品Key。

说明:如果传入该参数,需同时传入 DeviceName。

DeviceName String 否 文件所属的设备的名称。

说明:如果传入该参数,需同时传入 ProductKey。

FileId String 是 文件标识符。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

文档版本:20200417 141

Page 154: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "C25255EA-9F6E-4E04-85FE-AC1E9C136EBB", "Success": true}

• XML格式

<?xml version="1.0" encoding="utf-8"?><DeleteDeviceFileResponse> <RequestId>C25255EA-9F6E-4E04-85FE-AC1E9C136EBB</RequestId> <Success>true</Success></DeleteDeviceFileResponse>

1.1.2.8 分组管理

1.1.2.8.1 CreateDeviceGroup调用该接口新建分组。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:CreateDeviceGroup。

SuperGroupId

String 否 父组ID。

若要创建的是一级分组,则不传入此参数。

GroupName String 是 分组名称。名称可包含中文汉字、英文字母、数字和下划线(_)。长度范围 4 - 30 字符(一个中文汉字占二个字符)。

GroupDesc String 否 分组描述。长度限制为100字符(一个中文汉字占一个字符)。

142 文档版本:20200417

Page 155: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

Data Data 请参考下表Group。

表 1-56: Group

名称 类型 描述

GroupName String 分组名称。

UtcCreate Date 创建时间。

GroupDesc String 分组描述。

GroupId String 分组ID,系统为分组生成的全局唯一标识符。

示例

请求示例

返回示例

• JSON格式

{ "Data":{ "GroupDesc":"Group test", "GroupName":"grouptest", "UtcCreate":"2018-10-17T11:19:31.000Z", "GroupId":"HtMLECKbdJQL****" }, "RequestId":"4D6D7F71-1C94-4160-8511-EFF4B8F0634D", "Success":true

文档版本:20200417 143

Page 156: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><CreateDeviceGroupResponse> <Data> <GroupDesc>Group test</GroupDesc> <GroupName>grouptest</GroupName> <UtcCreate>2018-10-17T11:19:31.000Z</UtcCreate> <GroupId>HtMLECKbdJQL****</GroupId> </Data> <RequestId>4D6D7F71-1C94-4160-8511-EFF4B8F0634D</RequestId> <Success>true</Success></CreateDeviceGroupResponse>

1.1.2.8.2 UpdateDeviceGroup调用该接口修改分组信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:UpdateDeviceGroup。

GroupId String 是 分组ID。分组的全局唯一标识符。

GroupDesc String 否 修改后的分组描述。长度限制为100字符(一个中文汉字占一个字符)。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

示例

请求示例

返回示例

144 文档版本:20200417

Page 157: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "RequestId":"B78B4FD1-AE89-417B-AD55-367EBB0C6759", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" <UpdateDeviceGroupResponse> <RequestId>B78B4FD1-AE89-417B-AD55-367EBB0C6759</RequestId> <Success>true</Success></UpdateDeviceGroupResponse>

1.1.2.8.3 DeleteDeviceGroup调用该接口删除指定分组。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:DeleteDeviceGroup。

GroupId String 是 分组ID,分组的全局唯一标识符。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"B78B4FD1-AE89-417B-AD55-367EBB0C6759",

文档版本:20200417 145

Page 158: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" <DeleteDeviceGroupResponse> <RequestId>B78B4FD1-AE89-417B-AD55-367EBB0C6759</RequestId> <Success>true</Success></DeleteDeviceGroupResponse>

1.1.2.8.4 BatchAddDeviceGroupRelations调用该接口添加设备到某一分组(可批量添加设备)。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:BatchAddDeviceGroupRelations。

GroupId String 是 分组ID,分组的全局唯一标识符。

Devices List<Device>

是 要添加到分组的设备信息,请参见下表Device。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-57: Device

名称 类型 是否必需 描述

ProductKey String 是 要添加到分组的设备所属的产品Key。

DeviceName String 是 要添加到分组的设备名称。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示调用是否成功。true表示调用成功,false表示调用失败。

ErrorMessage String 返回的结果信息。

Code String 返回错误码,请参见错误码。

ValidDeviceCount

Integer 请求参数中合法的设备数量。

146 文档版本:20200417

Page 159: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

SuccessAddedDeviceCount

Integer 成功添加到分组的设备数量。

ExceedMaxGroupDeviceCount

Integer 请求参数中,已经添加到10个或者10个以上分组的设备数量(一个设备最多添加到10个分组)。

AlreadyRelatedGroupDeviceCount

Integer 原已经添加到此分组的设备数量。

示例

请求示例

返回示例

• JSON格式

{ "SuccessAddedDeviceCount":2, "ExceedTenGroupDeviceCount":0, "ErrorMessage":"2 devices have been added, and 0 devices failed to be added.", "ValidDeviceCount":2, "AlreadyRelatedGroupDeviceCount":0, "RequestId":"671D0F8F-FDC7-4B12-93FA-336C079C965A", "Success":true }

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><BatchAddDeviceGroupRelationsResponse> <SuccessAddedDeviceCount>2</SuccessAddedDeviceCount> <ExceedTenGroupDeviceCount>0</ExceedTenGroupDeviceCount> <ErrorMessage>2 devices have been added, and 0 devices failed to be added.</ErrorMessage> <ValidDeviceCount>2</ValidDeviceCount> <AlreadyRelatedGroupDeviceCount>0</AlreadyRelatedGroupDeviceCount> <RequestId>671D0F8F-FDC7-4B12-93FA-336C079C965A</RequestId> <Success>true</Success></BatchAddDeviceGroupRelationsResponse>

1.1.2.8.5 BatchDeleteDeviceGroupRelations调用该接口批量删除指定分组中的设备。(只删除设备与分组的关联关系,不会删除设备本身。)

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:BatchDeleteDeviceGroupRelations。

文档版本:20200417 147

Page 160: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

GroupId String 是 分组ID,分组的全局唯一标识符。

Devices List<Device>

是 要从分组中删除的设备信息,请参见下表Device。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-58: Device

名称 类型 是否必需 描述

ProductKey String 是 要从分组中删除的设备所属的产品Key。

DeviceName String 是 要从分组中删除的的设备名称。

返回参数

名称 类型 描述

ValidDeviceCount

Integer 请求参数中要删除的设备中,有效的设备数量(即可删除的设备数量)。

SuccessDeviceCount

Integer 成功从分组中删除的设备数量。

AlreadyRelatedGroupDeviceCount

Integer 删除前,已添加到此分组的设备数量。

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "SuccessDeviceCount":2,

148 文档版本:20200417

Page 161: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"ValidDeviceCount":2, "AlreadyRelatedGroupDeviceCount":2, "RequestId":"8739385E-143F-4389-B900-B7DF9174CE0D", "Success":true }

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><BatchDeleteDeviceGroupRelationsResponse> <SuccessDeviceCount>2</SuccessDeviceCount> <ValidDeviceCount>2</ValidDeviceCount> <AlreadyRelatedGroupDeviceCount>2</AlreadyRelatedGroupDeviceCount> <RequestId>8739385E-143F-4389-B900-B7DF9174CE0D</RequestId> <Success>true</Success></BatchDeleteDeviceGroupRelationsResponse>

1.1.2.8.6 QueryDeviceGroupInfo调用该接口查询分组详情。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QueryDeviceGroupInfo。

GroupId String 是 分组ID,分组的全局唯一标识符。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见#unique_104。

Data Data 调用成功时,返回的分组详细信息数据。请参考下表GroupInfo。

文档版本:20200417 149

Page 162: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-59: GroupInfo

名称 类型 描述

GroupName String 分组名称。

UtcCreate String 创建时间。

DeviceOnline Integer 在线设备数量。

DeviceActive Integer 激活设备数量。

DeviceCount Integer 设备总数。

GroupId String 分组ID。

GroupDesc String 分组描述。

示例

请求示例

返回示例

• JSON格式

{ "Data":{ "DeviceOnline":0, "DeviceActive":1, "GroupName":"yanglv", "DeviceCount":10, "UtcCreate":"2018-09-14T14:35:51.000Z", "GroupId":"tDQvBJqbUyHskDse" }, "RequestId":"7411716B-A488-4EEB-9AA0-6DB05AD2491F", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceGroupInfoResponse> <Data> <DeviceOnline>0</DeviceOnline> <DeviceActive>1</DeviceActive> <GroupName>yanglv</GroupName> <DeviceCount>10</DeviceCount> <UtcCreate>2018-09-14T14:35:51.000Z</UtcCreate> <GroupId>tDQvBJqbUyHskDse</GroupId> </Data> <RequestId>7411716B-A488-4EEB-9AA0-6DB05AD2491F</RequestId> <Success>true</Success>

150 文档版本:20200417

Page 163: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryDeviceGroupInfoResponse>

1.1.2.8.7 QueryDeviceGroupList调用该接口分页查询分组列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QueryDeviceGroupList。

GroupName String 否 分组名称。

• 传入分组名称,则根据名称进行查询。支持分组名称模糊查询。

• 若不传入此参数,则进行全量分组查询。

SuperGroupId

String 否 父组ID。查询某父组下的子分组列表时,需传入此参数。

PageSize Integer 否 每页记录数。最大值是200。默认值是10。

CurrentPage Integer 否 指定从返回结果中的第几页开始显示。默认值为1。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

PageCount Integer 总页数。

PageSize Integer 每页记录数。

CurrentPage Integer 当前页号。

Total Integer 总记录数。

文档版本:20200417 151

Page 164: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Data Data 调用成功时,返回的分组信息。请参见下表GroupInfo。

说明:返回的分组信息按照分组创建时间倒序排列。

表 1-60: GroupInfo

名称 类型 描述

GroupName String 分组名称。

UtcCreate Date 分组创建时间。

GroupDesc String 分组描述。

GroupId String 分组ID。

示例

请求示例

返回示例

• JSON格式

{ "PageCount":3, "Data":{ "GroupInfo":[ { "GroupName":"test1", "UtcCreate":"2018-10-09T02:58:34.000Z", "GroupId":"Kzt9FD8wje8o****" }, { "GroupName":"test2", "UtcCreate":"2018-10-09T02:56:40.000Z", "GroupId":"0ayrSQ3DSd7uXXXC" }, { "GroupDesc":"Test", "GroupName":"test3", "UtcCreate":"2018-09-16T05:38:27.000Z", "GroupId":"oWXlIQeFZtzC****" }, { "GroupName":"ylv0915", "UtcCreate":"2018-09-15T04:51:56.000Z", "GroupId":"SfEiVapLPUjB****" }, { "GroupName":"ydlv", "UtcCreate":"2018-09-14T14:35:51.000Z", "GroupId":"z2S2h9NsDTZm****"

152 文档版本:20200417

Page 165: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}, { "GroupName":"ldh_group_3", "UtcCreate":"2018-09-14T12:26:20.000Z", "GroupId":"chn5fkjinXGc7pGl" }, { "GroupDesc":"ddd", "GroupName":"ylvgisbim", "UtcCreate":"2018-09-14T11:41:20.000Z", "GroupId":"ncUZ8DjWYaB9****" }, { "GroupName":"abc", "UtcCreate":"2018-09-14T09:14:30.000Z", "GroupId":"zpdvwxzBdt4F****" }, { "GroupName":"test11", "UtcCreate":"2018-09-14T07:22:39.000Z", "GroupId":"BTaudF16X2xK****" }, { "GroupName":"testy", "UtcCreate":"2018-09-14T01:58:06.000Z", "GroupId":"PrTm3VOeggPw****" } ] }, "PageSize":10, "RequestId":"BEFCA316-D6C7-470C-81ED-1FF4FFD4AA0D", "CurrentPage":1, "Success":true, "Total":24}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceGroupListResponse> <PageCount>3</PageCount> <Data> <GroupInfo> <GroupName>test1</GroupName> <UtcCreate>2018-10-09T02:58:34.000Z</UtcCreate> <GroupId>Kzt9FD8wje8o****</GroupId> </GroupInfo> <GroupInfo> <GroupName>test2</GroupName> <UtcCreate>2018-10-09T02:56:40.000Z</UtcCreate> <GroupId>0ayrSQ3DSd7u****</GroupId> </GroupInfo> <GroupInfo> <GroupDesc>Test</GroupDesc> <GroupName>test3</GroupName> <UtcCreate>2018-09-16T05:38:27.000Z</UtcCreate> <GroupId>oWXlIQeFZtzC****</GroupId> </GroupInfo> <GroupInfo> <GroupName>ylv0915</GroupName> <UtcCreate>2018-09-15T04:51:56.000Z</UtcCreate> <GroupId>SfEiVapLPUjBVvSq</GroupId> </GroupInfo>

文档版本:20200417 153

Page 166: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<GroupInfo> <GroupName>ydlv</GroupName> <UtcCreate>2018-09-14T14:35:51.000Z</UtcCreate> <GroupId>z2S2h9NsDTZm****</GroupId> </GroupInfo> <GroupInfo> <GroupName>ldh_group_3</GroupName> <UtcCreate>2018-09-14T12:26:20.000Z</UtcCreate> <GroupId>chn5fkjinXGc****</GroupId> </GroupInfo> <GroupInfo> <GroupDesc>ddd</GroupDesc> <GroupName>ylvgisbim</GroupName> <UtcCreate>2018-09-14T11:41:20.000Z</UtcCreate> <GroupId>ncUZ8DjWYaB9****</GroupId> </GroupInfo> <GroupInfo> <GroupName>abc</GroupName> <UtcCreate>2018-09-14T09:14:30.000Z</UtcCreate> <GroupId>zpdvwxzBdt4F****</GroupId> </GroupInfo> <GroupInfo> <GroupName>test11</GroupName> <UtcCreate>2018-09-14T07:22:39.000Z</UtcCreate> <GroupId>BTaudF16X2xK****</GroupId> </GroupInfo> <GroupInfo> <GroupName>testy</GroupName> <UtcCreate>2018-09-14T01:58:06.000Z</UtcCreate> <GroupId>PrTm3VOeggPw****</GroupId> </GroupInfo> </Data> <PageSize>10</PageSize> <RequestId>BEFCA316-D6C7-470C-81ED-1FF4FFD4AA0D</RequestId> <CurrentPage>1</CurrentPage> <Success>true</Success> <Total>24</Total></QueryDeviceGroupListResponse>

1.1.2.8.8 SetDeviceGroupTags调用该接口添加、更新、或删除分组标签。

限制说明

单个分组最多可有100个标签。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:SetDeviceGroupTags

GroupId String 是 分组ID,分组的全局唯一标识符。

154 文档版本:20200417

Page 167: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

TagString String 是 JSON格式的标签数据。TagString由标签的tagKey和tagValue组成,tagKey和tagValue均不能为空。多个标签以英文逗号间隔。如,[{"tagKey":"h1","tagValue":"rr"},{"tagKey":"7h","tagValue":"rr"}]。请参见下表TagString。

若更新已有标签,新的标签value值将覆盖原来

的值。

若要删除某个标签,则不传入该标签的key和

value即可。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-61: TagString

名称 类型 是否必需 描述

tagKey String 是 标签键。可包含英文大小写字母,数字和点号(.),长度在2-30字符之间。

tagValue String 是 标签值。可包含中文、英文字母、数字、下划线(_)和连字符(-)。长度不可超过128字符。一个中文汉字算2字符。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

示例

请求示例

返回示例

文档版本:20200417 155

Page 168: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "RequestId":"12CFDAF1-99D9-42E0-8C2F-F281DA5E8953", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><SetDeviceGroupTagsResponse> <RequestId>12CFDAF1-99D9-42E0-8C2F-F281DA5E8953</RequestId> <Success>true</Success></SetDeviceGroupTagsResponse>

1.1.2.8.9 QueryDeviceGroupTagList调用该接口查询分组标签列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QueryDeviceGroupTagList。

GroupId String 是 分组ID,分组的全局唯一标识符。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

Data Data 调用成功时,返回的标签信息。请参见下表GroupTagInfo。

表 1-62: GroupTagInfo

名称 类型 描述

TagKey String 标签键。

156 文档版本:20200417

Page 169: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

TagValue String 标签值。

示例

请求示例

返回示例

• JSON格式

{ "Data":{ "GroupTagInfo":[ { "TagValue":"bulb", "TagKey":"room1" } ] }, "RequestId":"214154FF-9D47-4E3F-AAAD-F4CE67F41060", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceGroupTagListResponse> <Data> <GroupTagInfo> <TagValue>bulb</TagValue> <TagKey>room1</TagKey> </GroupTagInfo> </Data> <RequestId>214154FF-9D47-4E3F-AAAD-F4CE67F41060</RequestId> <Success>true</Success></QueryDeviceGroupTagListResponse>

1.1.2.8.10 QueryDeviceGroupByDevice调用该接口查询某一设备所在的分组列表。

限制说明

一个设备最多能被添加到10个分组中 。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryDeviceGroupByDevice。

ProductKey String 是 产品Key。

文档版本:20200417 157

Page 170: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

DeviceName String 是 设备名称。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

Code String 调用失败时,返回的错误码。请参见#unique_104。

ErrorMessage String 调用失败时,返回的错误信息。

GroupInfos List<GroupInfo> 调用成功时,返回的分组信息。详情请参见下表GroupInfo。

表 1-63: GroupInfo

名称 类型 描述

GroupId String 分组ID。

GroupName String 分组名称。

UtcCreate String 分组的创建时间。

GroupDesc String 分组描述。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "7941C8CD-7764-4A94-8CD9-E2762D4A73AC", "GroupInfos": { "GroupInfo": [ { "GroupDesc": "father desc", "GroupName": "father1543152336554", "UtcCreate": "2018-11-25T13:25:37.000Z", "GroupId": "6a3FF2XE2BKa****" }

158 文档版本:20200417

Page 171: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

] }, "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceGroupByDeviceResponse> <RequestId>7941C8CD-7764-4A94-8CD9-E2762D4A73AC</RequestId> <GroupInfos> <GroupInfo> <GroupDesc>father desc</GroupDesc> <GroupName>father1543152336554</GroupName> <UtcCreate>2018-11-25T13:25:37.000Z</UtcCreate> <GroupId>6a3FF2XE2BKayWsM</GroupId> </GroupInfo> </GroupInfos> <Success>true</Success></QueryDeviceGroupByDeviceResponse>

1.1.2.8.11 QuerySuperDeviceGroup调用该接口根据子分组ID查询父分组信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QuerySuperDeviceGroup。

GroupId String 是 子分组ID,分组的全局唯一标识符。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

Data Data 调用成功时,返回的父分组信息数据。请参考下表GroupInfo。

文档版本:20200417 159

Page 172: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

表 1-64: GroupInfo

名称 类型 描述

GroupName String 子分组所属的父分组名称。

GroupId String 子分组所属的父分组ID。

GroupDesc String 父分组描述。

示例

请求示例

返回示例

• JSON 格式

{ "Data":{ "GroupName":"IOTTEST", "GroupId":"tDQvBJqbUyHskDse", "GroupDesc":"A test." }, "RequestId":"7411716B-A488-4EEB-9AA0-6DB05AD2491F", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QuerySuperDeviceGroupResponse> <Data> <GroupName>IOTTEST</GroupName> <GroupId>tDQvBJqbUyHskDse</GroupId> <GroupDesc>A test.</GroupDesc> </Data> <RequestId>7411716B-A488-4EEB-9AA0-6DB05AD2491F</RequestId> <Success>true</Success></QuerySuperDeviceGroupResponse>

1.1.2.8.12 QueryDeviceListByDeviceGroup调用该接口查询分组中的设备列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QueryDeviceListByDeviceGroup。

GroupId String 是 分组ID,分组的全局唯一标识符。

CurrentPage Integer 否 指定显示查询结果中的第几页。默认值为1。

160 文档版本:20200417

Page 173: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

PageSize Integer 否 指定返回结果中,每页显示的设备数量。默认值为10。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 返回错误码,请参见错误码。

Page Integer 当前页码。

PageSize Integer 每页所显示的设备数量。

PageCount Integer 总页数。

Total Integer 设备总数。

Data List 调用成功时,返回的设备列表信息数据。详情请参见下表SimpleDeviceInfo。

表 1-65: SimpleDeviceInfo

名称 类型 描述

ProductName String 设备所属的产品名称。

ProductKey String 设备所属的产品Key。

DeviceName String 设备名称。

IotId String 物联网平台为该设备颁发的ID,作为该设备的唯一标识符。

示例

请求示例

返回示例

文档版本:20200417 161

Page 174: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "PageCount": 1, "Data": { "SimpleDeviceInfo": [ { "DeviceName": "ios_1207_08", "ProductKey": "a1hWjHD****", "ProductName": "WIFIdevice", "IotId": "TfmUAeJjQQhCPH84UVNn0010c6****" }, { "DeviceName": "ios_1207_07", "ProductKey": "a1hWjHD****", "ProductName": "WIFIgateway", "IotId": "wVPeAksaboXBlRgvZNHQ001031****" }, { "DeviceName": "E1IPK25iL4CTOwnuI2yt", "ProductKey": "a1mV8bK****", "ProductName": "yanlv", "IotId": "E1IPK25iL4CTOwnuI2yt001059****" } ] }, "PageSize": 10, "Page": 1, "RequestId": "B1A921D9-1061-4D45-9F12-EA6B0FDEDE30", "Success": true, "Total": 3}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryDeviceListByDeviceGroupResponse> <PageCount>1</PageCount> <Data> <SimpleDeviceInfo> <DeviceName>ios_1207_08</DeviceName> <ProductKey>a1hWjHD****</ProductKey> <ProductName>WIFIdevice</ProductName> <IotId>TfmUAeJjQQhCPH84UVNn0010c6****</IotId> </SimpleDeviceInfo> <SimpleDeviceInfo> <DeviceName>ios_1207_07</DeviceName> <ProductKey>a1hWjHD****</ProductKey> <ProductName>WIFIgateway</ProductName> <IotId>wVPeAksaboXBlRgvZNHQ001031****</IotId> </SimpleDeviceInfo> <SimpleDeviceInfo> <DeviceName>E1IPK25iL4CTOwnuI2yt</DeviceName> <ProductKey>a1mV8bK****</ProductKey> <ProductName>yanlv</ProductName> <IotId>E1IPK25iL4CTOwnuI2yt001059****</IotId> </SimpleDeviceInfo> </Data> <PageSize>10</PageSize> <Page>1</Page> <RequestId>B1A921D9-1061-4D45-9F12-EA6B0FDEDE30</RequestId> <Success>true</Success>

162 文档版本:20200417

Page 175: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<Total>3</Total></QueryDeviceListByDeviceGroup>

1.1.2.8.13 QueryDeviceGroupByTags调用该接口根据标签查询设备分组。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作。取值:QueryDeviceGroupByTags。

Tags List 是 标签列表。Tag由TagKey和TagValue组成。具体请参见下表Tag。

• 支持根据TagKey和TagValue查询。• 也支持只输入TagKey进行查询。

CurrentPage Integer 否 指定显示查询结果的第几页。默认值是1。

PageSize Integer 否 指定每页显示的记录数。默认值是10。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-66: Tag

名称 类型 是否必需 描述

TagKey String 是 分组标签键(key)。

TagValue String 否 分组标签值(value)。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

PageCount Integer 总页数。

PageSize Integer 每页显示的记录数。

文档版本:20200417 163

Page 176: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Page Integer 当前页码。

Total Integer 总记录数。

Data Data 调用成功时,返回分组信息。详情见下表DeviceGroup。

表 1-67: DeviceGroup

名称 类型 描述

GroupName String 分组名称。

GroupID String 分组ID。

示例

请求示例

返回示例

• JSON格式

{ "PageCount": 1, "Data": { "DeviceGroup": [ { "GroupName": "test11", "GroupId": "Z0ElGF5aqc0t****" } ] }, "Page": 1, "PageSize": 10, "RequestId": "9599EE98-1642-4FCD-BFC4-039E458A4693", "Success": true, "Total": 1}

• XML格式

<?xml version="1.0" encoding="utf-8"?><QueryDeviceGroupByTagsResponse> <PageCount>1</PageCount> <Data> <DeviceGroup> <GroupName>test11</GroupName> <GroupId>Z0ElGF5aqc0t****</GroupId> </DeviceGroup> </Data> <Page>1</Page> <PageSize>10</PageSize> <RequestId>9599EE98-1642-4FCD-BFC4-039E458A4693</RequestId> <Success>true</Success> <Total>1</Total>

164 文档版本:20200417

Page 177: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryDeviceGroupByTagsResponse>

1.1.2.9 Topic管理

1.1.2.9.1 CreateProductTopic调用该接口为指定产品创建产品Topic类。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:CreateProductTopic。

ProductKey String 是 要为其创建Topic类的产品Key。

TopicShortName

String 是 设置Topic类的自定义类目名称。Topic类

默认包含productKey和deviceName两

级类目,类目间以正斜线(/)分隔,其

格式为:productKey/deviceName/

topicShortName。

说明:每级类目的名称只能包含字母、数字和下划线(_),且不能为空。

Operation String 是 设备对该Topic类的操作权限,取值:

SUB:订阅。

PUB:发布。

ALL:发布和订阅。

Desc String 否 Topic类的描述信息。长度限制为100字符(一个汉字占一个字符)。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

文档版本:20200417 165

Page 178: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

TopicId Long 调用成功时,物联网平台为新建的Topic类生成的Topic ID

说明:请妥善保管该信息。在调用与该Topic类相关的接口时,您可能需要提供对应的Topic ID。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true, "TopicId":10000}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><CreateProductTopicResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success> <TopicId>10000</TopicId></CreateProductTopicResponse>

1.1.2.9.2 UpdateProductTopic调用该接口更新指定的产品Topic类。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:UpdateProductTopic。

TopicId Long 是 要修改的Topic类的 ID。

166 文档版本:20200417

Page 179: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

TopicShortName

String 否 设置Topic类的自定义类目名称。Topic类

默认包含productKey和deviceName两

级类目,类目间以正斜线(/)分隔,其

格式为:productKey/deviceName/

topicShortName。

说明:每级类目的名称只能包含字母、数字和下划线(_),且不能为空。

Operation String 否 设备对该Topic类的操作权限,取值:

SUB:订阅。

PUB:发布。

ALL:发布和订阅。

Desc String 否 Topic类的描述信息。长度限制为100字符(一个汉字占一个字符)。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

文档版本:20200417 167

Page 180: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><UpdateProductTopicResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success></UpdateProductTopicResponse>

1.1.2.9.3 QueryProductTopic调用该接口查询指定产品的Topic类。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryProductTopic。

ProductKey String 是 要查询Topic类的产品Key。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

Data ProductTopicInfo 调用成功时,返回的Topic类信息列表。详情参见下表ProductTopicInfo。

表 1-68: ProductTopicInfo

名称 类型 描述

ProductKey String 产品Key。

168 文档版本:20200417

Page 181: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Id String Topic类的 ID。

TopicShortName

String Topic类中除productKey和deviceName以外的类目。

Operation String 设备对该Topic类的操作权限,取值:

0:发布

1:订阅

2:发布和订阅

Desc String Topic类的描述信息。

示例

请求示例

返回示例

• JSON格式

{ "Data": [{ "Id": "10000", "Operation": "0", "ProductKey": "HMyB***", "TopicShortName": "/HMyB***/${deviceName}/update" }, { "Id": "10001", "Operation": "2", "ProductKey": "HMyB***", "TopicShortName": "/HMyB***/${deviceName}/update/error" }, { "Id": "10002", "Operation": "1", "ProductKey": "HMyB***", "TopicShortName": "/HMyB***/${deviceName}/get" }], "RequestId": "B953EAFF-CFF6-4FF8-BC94-8B89F018E4DD", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryProductTopicResponse> <Data> <Id>10000</Id> <Operation>0</Operation> <ProductKey>HMyB***</ProductKey> <TopicShortName>/HMyB***/${deviceName}/update</TopicShortName>

文档版本:20200417 169

Page 182: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</Data> <Data> <Id>10001</Id> <Operation>2</Operation> <ProductKey>HMyB***</ProductKey> <TopicShortName>/HMyB***/${deviceName}/update/error</TopicShortName> </Data> <Data> <Id>10002</Id> <Operation>1</Operation> <ProductKey>HMyB***</ProductKey> <TopicShortName>/HMyB***/${deviceName}/get</TopicShortName> </Data> <RequestId>B953EAFF-CFF6-4FF8-BC94-8B89F018E4DD</RequestId> <Success>true</Success></QueryProductTopicResponse>

1.1.2.9.4 DeleteProductTopic调用该接口删除指定的Topic类。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteProductTopic。

TopicId Long 是 要删除的Topic类的 ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{

170 文档版本:20200417

Page 183: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><DeleteProductTopicResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success></DeleteProductTopicResponse>

1.1.2.9.5 CreateTopicRouteTable调用该接口新建Topic间的消息路由关系。

限制说明

• 一个源Topic最多可对应100个目标Topic。

• 源Topic所属的设备必须为已激活设备。

• 源Topic和目标Topic均不能是以 sys 开头的系统 Topic。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:CreateTopicRouteTable。

SrcTopic String 是 源Topic,即被订阅的Topic。如,SrcTopic=/x7aWKW9****/testDataToDataHub/update。

DstTopic List 是 目标Topic列表,即从SrcTopic订阅消息的Topic列表。即使只有一个Topic,也使用数组格式。如,DstTopic.1=/x7aWKW9****/deviceNameTest1/add,DstTopic.2=/x7aWKW9****/deviceNameTest2/delete。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

文档版本:20200417 171

Page 184: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

FailureTopics List 未能成功创建路由关系的Topic列表。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true, "FailureTopics":[]}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><CreateTopicRouteTableResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success> <FailureTopics>...</FailureTopics></CreateTopicRouteTableResponse>

1.1.2.9.6 DeleteTopicRouteTable调用该接口删除指定的Topic路由关系。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteTopicRouteTable。

SrcTopic String 是 源Topic,即被订阅的Topic。如,SrcTopic.1=/x7aWKW9****/testDataToDataHub/update。

DstTopic List 是 目标Topic列表,即从SrcTopic订阅消息的Topic列表。如,DstTopic.1=/x7aWKW9****/deviceNameTest1/add,DstTopic.2=/x7aWKW9****/deviceNameTest2/delete。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

172 文档版本:20200417

Page 185: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

FailureTopics List 未能成功删除路由关系的Topic列表。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true, "FailureTopics":[]}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><DeleteTopicRouteTableResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success> <FailureTopics>...</FailureTopics></DeleteTopicRouteTableResponse>

1.1.2.9.7 QueryTopicReverseRouteTable调用该接口查询指定Topic订阅的源Topic,即反向路由表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryTopicReverseRouteTable。

Topic String 是 要查询的目标Topic,即接收消息的Topic。

文档版本:20200417 173

Page 186: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

SrcTopics List 调用成功时,返回的源Topic列表,即被订阅的Topic列表。

示例

请求示例

https://应用网关IP:port/data/api.json/?Action=QueryTopicReverseRouteTable&Topic=%2Fx7aWKW94bb8%2FtestDataToDataHub%2Fupdate&公共请求参数

返回示例

• JSON格式

{ "RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true, "SrcTopics":["/CXi4***/device1/get","/CXi4***/device4/get"]}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryTopicReverseRouteTableResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success> <SrcTopics>/CXi4***/device1/get</SrcTopics> <SrcTopics>/CXi4***/device4/get</SrcTopics>

174 文档版本:20200417

Page 187: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</QueryTopicReverseRouteTableResponse>

1.1.2.9.8 QueryTopicRouteTable调用该接口查询向指定Topic订阅消息的目标Topic,即指定Topic的路由表。该接口只支持查询用户

的Topic。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:QueryTopicRouteTable。

Topic String 是 要查询的源Topic,即发布消息的Topic。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

DstTopics List 调用成功时,返回的目标Topic列表,即向源Topic订阅消息的Topic列表。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"FCC27691-9151-4B93-9622-9C90F30542EC", "Success":true, "DstTopics":["/CXi4***/device2/get","/CXi4***/device3/get"]

文档版本:20200417 175

Page 188: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><QueryTopicRouteTableResponse> <RequestId>FCC27691-9151-4B93-9622-9C90F30542EC</RequestId> <Success>true</Success> <DstTopics>/CXi4***/device2/get</DstTopics> <DstTopics>/CXi4***/device3/get</DstTopics></QueryTopicRouteTableResponse>

1.1.2.10 规则引擎

1.1.2.10.1 CreateRule调用该接口对指定Topic新建一个规则。

请求参数

说明:

如需启动规则,需包含ProductKey、ShortTopic、Select三个参数的信息。

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:CreateRule。

Name String 是 规则名称。支持使用中英文字符、数字和下划线(_),长度应为4~30位(一个中文字符算2位)。

ProductKey String 否 应用该规则的产品Key。

176 文档版本:20200417

Page 189: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ShortTopic String 否 应用该规则的具体Topic,格式为:${

deviceName}/topicShortName。其

中,${deviceName}指具体设备的名

称,topicShortName是自定义类目。

调用QueryDevice接口,查看产品下的所有设

备。返回结果中包含所有的DeviceName。

调用UpdateProductTopic接口,查看产品

下的所有Topic类。返回结果中包含所有的

TopicShortName。

示例:

• 系统Topic的ShortTopic,如:${

deviceName}/thing/event/property/post

,其中${deviceName}可以使用通配符+代

替,表示产品下所有设备名称。

• 自定义Topic的ShortTopic,如:${

deviceName}/user/get。

指定自定义Topic时,可以使用通配符+和#。

- ${deviceName}可以使用通配符+代

替,表示产品下所有设备;

- 之后字段可以用/user/#,#表示/user层

级之后的所有层级名称。

使用通配符,请参见 《用户指南》

中设备接入 > 消息通信Topic > 自定

义Topic中Topic类中的通配符。

• 设备状态Topic的ShortTopic:${deviceName}。

文档版本:20200417 177

Page 190: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Select String 否 要执行的SQL Select语句。具体内容参照 《用

户指南》 中消息通信 > 规则引擎 > 数据流转 >

SQL表达式。

说明:此处传入的是Select下的内容。例如,如果Selcet语句为Select a,b,c,则此处传入a,b,c。

RuleDesc String 否 规则的描述信息。长度限制为100字符(一个汉字占一个字符)。

DataType String 否 规则处理的数据格式,需与待处理的设备数据格

式一致。取值:

• JSON:JSON数据。• BINARY:二进制数据。

说明:若选择为BINARY,TopicType不能选择为0(系统Topic),且不能将数据转发至表格存储、时序时空数据库和云数据库RDS版。

如果不传入该参数,则默认使用JSON格式。

Where String 否 规则的触发条件。具体内容参照SQL表达式。

说明:此处传入的是Where中的内容。例如,如果Where语句为Where a>10,则此处传入a>10。

178 文档版本:20200417

Page 191: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

TopicType Integer 是 • 0:系统Topic,包含:

- /thing/event/property/post 设备上报的属性消息。

- /thing/event/${tsl.event.identifier}/post,${}中的是产品物模型中事件identifier。设备上报的事件消息

- thing/lifecycle 设备生命周期变更消息。- /thing/downlink/reply/message设备

响应云端指令的结果消息。- /thing/list/found网关上报发现子设备消

息。- thing/topo/lifecycle设备拓扑关系变更消

息。• 1:自定义Topic。

• 2:设备状态消息Topic:/as/mqtt/status/

${productKey}/${deviceName}。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

RuleId Long 调用成功时,规则引擎为该规则生成的规则ID,作为该规

则的标识符。

说明:请妥善保管该信息。在调用和规则相关的接口时,您可能需要提供对应的规则ID。

文档版本:20200417 179

Page 192: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "E4C0FF92-2A86-41DB-92D3-73B60310D25E", "RuleId": 1000, "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><CreateRuleResponse> <RequestId>E4C0FF92-2A86-41DB-92D3-73B60310D25E</RequestId> <RuleId>1000</RuleId> <Success>true</Success></CreateRuleResponse>

1.1.2.10.2 CreateRuleAction调用该接口在指定的规则下创建一个规则动作,定义将处理后的Topic数据转发至物联网平台的其

他Topic或所支持的其他阿里云服务。

限制说明

• 服务地域不同,所支持的目标云产品有所不同。规则引擎支持的地域及目标云产品,请与管理员

确认。

• 一个规则下面最多可创建10个规则动作。

• 您可以通过调用该API创建规则动作,定义将数据转发至物联网平台其他Topic和消息队列Kafka。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:CreateRuleAction。

RuleId Long 是 要为其创建动作的规则ID。

Type String 是 规则动作类型,取值:

• KAFKA:将根据规则处理后的Topic数据转发至阿里云消息队列Kafka,进行消息分发。

• REPUBLISH:将根据规则处理后的Topic数据转发至另一个物联网平台 Topic。

180 文档版本:20200417

Page 193: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Configuration

String 是 该规则动作的配置信息。不同规则动作类型所需内容不同,具体要求见下文描述。

ErrorActionFlag

String 否 该规则动作是否为转发错误操作数据的转发动作,即转发流转到其他云产品失败且重试失败的数据。 可选值:

• true:该规则动作转发错误操作数据。• false:该规则动作不转发错误操作数据,而

是正常转发操作。

默认值为false。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

REPUBLISH类型Configuration定义

表 1-69: REPUBLISH Configuration

名称 描述

topic 转发至的目标Topic(系统Topic或自定义Topic

)。

支持将数据转发至数据下行的系统Topic:

• /sys/${YourProductKey}/${YourDevice

Name}/thing/service/property/set

• /sys/${YourProductKey}/${YourDevice

Name}/thing/service/${tsl.service.

identifier},变量${tsl.service.identifier}的

内容由该产品物模型中的服务决定。

topicType Topic的类型。

• 0表示数据下行系统Topic。• 1表示用户自定义Topic。

REPUBLISH 类型Configuration示例:

sys类型:{"topic":"/sys/a1TXXXXXWSN/xxx_cache001/thing/service/property/set","topicType":0}

文档版本:20200417 181

Page 194: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

自定义类型:{"topic":"/a1TXXXXXWSN/xxx_cache001/user/update","topicType":1}

KAFKA类型Configuration定义

说明:

您需通过调用消息队列Kafka的SDK,或在消息队列Kafka控制台,授权物联网平台访问消息队

列Kafka(至少要授予物联网平台发布权限),然后才能够成功创建将Topic数据转发至消息队

列Kafka的规则动作。

表 1-70: ONS Configuration

名称 描述

endpoint kafka服务的接入点,用于访问kafka服务。您可以自己部署kafka并提供接入点,也可以用底座自带的,地址可以请与部署人员或管理员确认。

topic Kafka中用来接收信息的目标Topic。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

ActionId Long 调用成功时,规则引擎为该规则动作生成的规则动作ID

,作为其标识符。

说明:请妥善保管该信息。在调用与规则动作相关的接口时,您可能需要提供对应的规则动作ID。

示例

请求示例

返回示例

• JSON格式

{

182 文档版本:20200417

Page 195: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"RequestId": "21D327AF-A7DE-4E59-B5D1-ACAC8C024555", "ActionId": 10003, "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><CreateRuleActionResponse> <RequestId>21D327AF-A7DE-4E59-B5D1-ACAC8C024555</RequestId> <ActionId>10003</ActionId> <Success>true</Success></CreateRuleActionResponse>

1.1.2.10.3 DeleteRule调用该接口删除指定的规则。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteRule。

RuleId Long 是 要删除的规则ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "A8F48485-44B9-40D8-A56D-F716F384F387", "Success": true

文档版本:20200417 183

Page 196: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><DeleteRuleResponse> <RequestId>A8F48485-44B9-40D8-A56D-F716F384F387</RequestId> <Success>true</Success></DeleteRuleResponse>

1.1.2.10.4 DeleteRuleAction调用该接口删除指定的规则动作。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:DeleteRuleAction。

ActionId Long 是 要删除的规则动作ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "8FC9E36B-E0DC-4802-84EE-184E255B4E95", "Success": true

184 文档版本:20200417

Page 197: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><DeleteRuleActionResponse> <RequestId>8FC9E36B-E0DC-4802-84EE-184E255B4E95</RequestId> <Success>true</Success></DeleteRuleActionResponse>

1.1.2.10.5 GetRule调用该接口查询指定规则的详细信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:GetRule。

RuleId Long 是 要查询的规则ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

RuleInfo RuleInfo 调用成功时,返回的规则详细信息。详情参见下表RuleInfo。

表 1-71: RuleInfo

名称 类型 描述

CreateUserId Long 创建该规则的用户ID。

Created String 该规则创建时的CST时间。

DataType String 该规则的数据类型,取值:JSON或BINARY。

Id Long 规则ID。

文档版本:20200417 185

Page 198: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Modified String 该规则最近一次被修改时的CST时间。

Name String 规则名称。

ProductKey String 应用该规则的产品Key。

RuleDesc String 规则的描述信息。

Select String 该规则SQL语句中的Select内容。

ShortTopic String 该规则所处理消息来源的具体Topic(不包含ProductKey类目),格式为:${deviceName}/topicShortName。其中,${deviceName}指具体设备的名称,topicShortName是该设备的自定义类目。

Status String 该规则的运行状态。取值:

RUNNING:运行中

STOP:停止

Topic String 该规则所处理消息来源的完整Topic,格式为:${productKey}/${deviceName}/topicShortName。

Where String 该规则SQL语句中的Where查询条件。

TopicType Integer 若您设置了规则SQL语句,则返回:

• 0:表示系统Topic。

• 1:表示自定义Topic。

• 2:表示设备状态Topic。

若未设置过规则SQL语句,则返回-1。

UtcCreated String 规则创建时的UTC时间。

UtcModified String 规则最近一次更新时的UTC时间。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "58D4CEC0-3E95-4DBE-AFC1-809D1400E52F", "Success": true, "RuleInfo": { "DataType": "JSON",

186 文档版本:20200417

Page 199: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"ShortTopic": "+/#", "ProductKey": "a1KiV******", "UtcModified": "2019-02-28T06:20:58.000Z", "CreateUserId": "12******85529123", "UtcCreated": "2019-02-28T06:14:33.000Z", "Name": "iotrules", "Status": "STOP", "Select": "deviceName() as deviceName", "Created": "Thu Feb 28 14:14:33 CST 2019", "Modified": "Thu Feb 28 14:20:58 CST 2019", "TopicType": 1, "Topic": "/a1KiV******/+/#", "Id": 100000 }}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><GetRuleResponse> <RequestId>58D4CEC0-3E95-4DBE-AFC1-809D1400E52F</RequestId> <Success>true</Success> <RuleInfo> <DataType>JSON</DataType> <ShortTopic>+/#</ShortTopic> <ProductKey>a1KiV******</ProductKey> <UtcModified>2019-02-28T06:20:58.000Z</UtcModified> <CreateUserId>1231579085******</CreateUserId> <UtcCreated>2019-02-28T06:14:33.000Z</UtcCreated> <Name>iotrules</Name> <Status>STOP</Status> <Select>deviceName() as deviceName</Select> <Created>Thu Feb 28 14:14:33 CST 2019</Created> <Modified>Thu Feb 28 14:20:58 CST 2019</Modified> <TopicType>1</TopicType> <Topic>/a1KiV******/+/#</Topic> <Id>100000</Id> </RuleInfo></GetRuleResponse>

1.1.2.10.6 GetRuleAction调用该接口查询指定规则动作的详细信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:GetRuleAction。

ActionId Long 是 要查询的规则动作ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

文档版本:20200417 187

Page 200: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

RuleActionInfo RuleActionInfo 调用成功时,返回的规则动作详细信息。详情参见下表RuleActionInfo。

表 1-72: RuleActionInfo

名称 类型 描述

Id Long 规则动作ID。

RuleId Long 该规则动作对应的规则ID。

Type String 规则动作类,取值:

REPUBLISH:转发到另一个topic。

Configuration String 该规则动作的配置信息。

ErrorActionFlag String 该规则动作是否为转发错误操作数据的转发动作,即转发流转到其他云产品失败且重试失败的数据。

• true:该规则动作转发错误操作数据。• false:该规则动作不转发错误操作数据,而是正常转发

操作。

示例

请求示例

返回示例

• JSON格式

{ "RuleActionInfo": { "Type": "REPUBLISH", "RuleId": 152323, "Id": 100001, "Configuration": "{\"topic\":\"/sys/a1zSA28HUyy/device/thing/service/property/set\",\"topicType\":0,\"uid\":\"1231579*******\"}", "ErrorActionFlag": false

188 文档版本:20200417

Page 201: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}, "RequestId": "F2D0755D-F350-40FE-9A6D-491859DB5E5F", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><GetRuleActionResponse> <RuleActionInfo> <Type>REPUBLISH</Type> <RuleId>152323</RuleId> <Id>100001</Id> <Configuration> <topic>/sys/a1zSA28HUyy/device/thing/service/property/set</topic> <topicType>0</topicType> <uid>1231579*******</uid> </Configuration> <ErrorActionFlag>false</ErrorActionFlag> </RuleActionInfo> <RequestId>F2D0755D-F350-40FE-9A6D-491859DB5E5F</RequestId> <Success>true</Success></GetRuleActionResponse>

1.1.2.10.7 ListRule调用该接口分页查询所有规则列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:ListRule。

PageSize Integer 是 返回结果中每页显示的记录数量。最大取值100,默认值是10。

CurrentPage Integer 是 显示返回结果中的第几页。最大取值 1000,默认值 1。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

文档版本:20200417 189

Page 202: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

Data RuleInfo 调用成功时,返回的规则信息列表。详情参见下表RuleInfo。

说明:返回规则信息按照规则创建时间倒序排列。

PageSize Integer 每页显示的记录数。

Page Integer 当前页码。

Total Integer 总页数。

表 1-73: RuleInfo

名称 类型 描述

CreateUserId Long 创建该规则的用户ID。

Created String 该规则创建时的CST(Central Standard Time)时间。

DataType String 该规则的数据类型,取值:JSON和BINARY。

Id Long 规则ID。

Modified String 该规则最近一次被修改时的CST (Central Standard Time)时间。

Name String 规则名称。

ProductKey String 应用该规则的产品Key。

RuleDesc String 规则的描述信息。

Select String 该规则SQL语句中的Select内容。

ShortTopic String 应用该规则的具体Topic(不包含ProductKey类目),格式为:${deviceName}/topicShortName。其中,${deviceName}指具体设备的名称,topicShortName是该设备的自定义类目。

Status String 该规则的运行状态。取值:

RUNNING:运行中

STOP:停止

Topic String 应用该规则的具体Topic,格式为:${productKey}/${deviceName}/topicShortName。

190 文档版本:20200417

Page 203: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

UtcModified String 该规则最近一次被修改时的UTC时间。

UtcCreated String 该规则创建时的UTC时间。

Where String 该规则SQL语句中的Where查询条件。

示例

请求示例

返回示例

• JSON格式

{ "Data": { "RuleInfo": [ { "DataType": "JSON", "ShortTopic": "+/#", "ProductKey": "a1KiV******", "CreateUserId": "1231579085******", "UtcModified": "2019-02-28T06:20:58.000Z", "UtcCreated": "2019-02-28T06:14:33.000Z", "Name": "iotrules", "Status": "STOP", "Select": "deviceName() as deviceName", "Created": "Thu Feb 28 14:14:33 CST 2019", "Modified": "Thu Feb 28 14:20:58 CST 2019", "Topic": "/a1KiV******/+/#", "Id": 152323 }, { "Name": "test123", "Status": "STOP", "Created": "Wed Feb 27 20:45:43 CST 2019", "DataType": "JSON", "Modified": "Wed Feb 27 20:45:43 CST 2019", "UtcModified": "2019-02-27T12:45:43.000Z", "CreateUserId": "1231579085******", "Id": 151454, "UtcCreated": "2019-02-27T12:45:43.000Z" } ] }, "PageSize": 2, "Page": 1, "RequestId": "1564B626-DE97-452D-9E9B-305888AC6105", "Success": true, "Total": 25}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><ListRuleResponse> <Data> <RuleInfo>

文档版本:20200417 191

Page 204: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<DataType>JSON</DataType> <ShortTopic>+/#</ShortTopic> <ProductKey>a1KiV******</ProductKey> <CreateUserId>1231579085******</CreateUserId> <UtcModified>2019-02-28T06:20:58.000Z</UtcModified> <UtcCreated>2019-02-28T06:14:33.000Z</UtcCreated> <Name>iotrules</Name> <Status>STOP</Status> <Select>deviceName() as deviceName</Select> <Created>Thu Feb 28 14:14:33 CST 2019</Created> <Modified>Thu Feb 28 14:20:58 CST 2019</Modified> <Topic>/a1KiV******/+/#</Topic> <Id>152323</Id> </RuleInfo> <RuleInfo> <Name>test123</Name> <Status>STOP</Status> <Created>Wed Feb 27 20:45:43 CST 2019</Created> <DataType>JSON</DataType> <Modified>Wed Feb 27 20:45:43 CST 2019</Modified> <UtcModified>2019-02-27T12:45:43.000Z</UtcModified> <CreateUserId>1231579085******</CreateUserId> <Id>151454</Id> <UtcCreated>2019-02-27T12:45:43.000Z</UtcCreated> </RuleInfo> </Data> <PageSize>2</PageSize> <Page>1</Page> <RequestId>87B1B7C3-FD90-4B80-93BC-A52F7996A903</RequestId> <Success>true</Success> <Total>25</Total></ListRuleResponse>

1.1.2.10.8 ListRuleActions调用该接口查询指定规则下的所有规则动作列表。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:ListRuleActions。

RuleId String 是 要查询的规则ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

192 文档版本:20200417

Page 205: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

RuleActionList RuleActionInfo 调用成功时,返回的规则动作信息列表。详情参见下表RuleActionInfo。

表 1-74: RuleActionInfo

名称 类型 描述

Id Long 规则动作ID。

RuleId Long 该规则动作对应的规则ID。

Type String 规则动作类型。取值:

REPUBLISH:转发到另一个topic。

ONS:发送数据到消息队列。

Configuration String 该规则动作的配置信息。

ErrorActionFlag String 该规则动作是否为转发错误操作数据的转发动作,即转发流转到其他云产品失败且重试失败的数据。

• true:该规则动作转发错误操作数据。• false:该规则动作不转发错误操作数据,而是正常转发

操作。

示例

请求示例

返回示例

• JSON格式

{ "RuleActionList": { "RuleActionInfo": [ { "Type": "REPUBLISH", "RuleId": 152323, "Id": 142401, "Configuration": "{\"topic\":\"/sys/a1zSA28H***/device/thing/service/property/set\",\"topicType\":0,\"uid\":\"1231579085******\"}", "ErrorActionFlag": false } ] },

文档版本:20200417 193

Page 206: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

"RequestId": "22254BDB-3DC1-4643-8D1B-EE0437EF09A9", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><ListRuleActionsResponse> <RuleActionList> <RuleActionInfo> <Type>REPUBLISH</Type> <RuleId>152323</RuleId> <Id>142401</Id> <Configuration> <topic>/sys/a1zSA28HUyy/device/thing/service/property/set</topic> <topicType>0</topicType> <uid>1231579*******</uid> </Configuration> <ErrorActionFlag>false</ErrorActionFlag> </RuleActionInfo> </RuleActionList> <RequestId>22254BDB-3DC1-4643-8D1B-EE0437EF09A9</RequestId> <Success>true</Success></ListRuleActionsResponse>

1.1.2.10.9 StartRule调用该接口启动指定的规则。

请求参数

说明:

启动规则前需要确认该规则已经配置了SQL。配置SQL,参考CreateRule接口。

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:StartRule。

RuleId Long 是 要启动的规则ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

194 文档版本:20200417

Page 207: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Code String 调用失败时,返回的错误码。错误码详情,请参见#unique_104。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"9A2F243E-17FE-4846-BAB5-D02A25155AC4", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><StartRuleResponse> <RequestId>9A2F243E-17FE-4846-BAB5-D02A25155AC4</RequestId> <Success>true</Success></StartRuleResponse>

1.1.2.10.10 StopRule调用该接口停止指定的规则。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:StopRule。

RuleId Long 是 指要停止的规则ID。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

文档版本:20200417 195

Page 208: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"9A2F243E-17FE-4846-BAB5-D02A25155AC4", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><StopRuleResponse> <RequestId>9A2F243E-17FE-4874-QBB5-D02A25155AC8</RequestId> <Success>true</Success></StopRuleResponse>

1.1.2.10.11 UpdateRule调用该接口修改指定的规则。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:UpdateRule。

RuleId Long 是 要修改的规则ID。

Name String 是 规则名称。支持使用中英文字符、数字和下划线(_),长度应为4~30位(一个中文字符算2位)。

ProductKey String 否 应用该规则的产品Key。

196 文档版本:20200417

Page 209: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ShortTopic String 否 应用该规则的具体Topic,格式为:${

deviceName}/topicShortName。其

中,${deviceName}指具体设备的名

称,topicShortName是自定义类目。

调用QueryDevice接口,查看产品下的所有设

备。返回结果中包含所有的DeviceName。

调用UpdateProductTopic接口,查看产品

下的所有Topic类。返回结果中包含所有的

TopicShortName。

示例:

• 系统Topic的ShortTopic,如:${

deviceName}/thing/event/property/

post,其中${deviceName}可以使用通配

符+代替,表示产品下所有设备名称。

• 自定义Topic的ShortTopic,如:${

deviceName}/user/get。

指定自定义Topic时,可以使用通配

符+和#。

- ${deviceName}可以使用通配符+代

替,表示产品下所有设备;

- 之后字段可以用/user/#,#表示/user层

级之后的所有层级名称。

使用通配符,请参见 《用户指南》

中设备接入 > 消息通信Topic > 自定

义Topic中Topic类中的通配符。

• 设备状态Topic的ShortTopic:${deviceName}。

文档版本:20200417 197

Page 210: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Select String 否 要执行的SQL Select语句。具体内容参照SQL表

达式。

说明:此处传入的是Select下的内容。例如,如果Selcet语句为Select a,b,c,则此处传入a,b,c。

RuleDesc String 否 规则的描述信息。长度限制为100字符(一个汉字占一个字符)。

Where String 否 规则的触发条件。具体内容参照SQL表达式。

说明:此处传入的是Where中的内容。例如,如果Where语句为Where a>10,则此处传入a>10。

TopicType Integer 否 • 0:系统Topic,包含:

- /thing/event/property/post 设备上报的属性消息。

- /thing/event/${tsl.event.identifier}/post,${}中的是产品物模型中事件identifier。设备上报的事件消息

- thing/lifecycle 设备生命周期变更消息。

- /thing/downlink/reply/message设备响应云端指令的结果消息。

- /thing/list/found网关上报发现子设备消息。

- thing/topo/lifecycle设备拓扑关系变更消息。

• 1:自定义Topic。

• 2:设备状态消息Topic:/as/mqtt/status/

${productKey}/${deviceName}。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

198 文档版本:20200417

Page 211: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"9A2F243E-17FE-4846-BAB5-D02A25155AC4", "Success":true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><UpdateRuleResponse> <RequestId>9A2F243E-17FE-4874-QBB5-D02A25155AC8</RequestId> <Success>true</Success></UpdateRuleResponse>

1.1.2.10.12 UpdateRuleAction调用该接口修改指定的规则动作。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:UpdateRuleAction。

ActionId Long 是 要修改的规则动作ID。

Type String 是 规则动作类型,取值:

REPUBLISH:流转规则处理后的Topic数据至

另一个物联网平台 Topic。

文档版本:20200417 199

Page 212: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Configuration String 是 该规则动作的配置信息。不同规则动作类型所需配置内容不同。具体要求,请参见CreateRuleAction中的各规则动作类型的Configuration描述。

IotInstanceId String 否 共享实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功, false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId": "21D327AF-A7DE-4E59-B5D1-ACAC8C024555", "Success": true}

• XML格式

<?xml version="1.0" encoding="UTF-8" ?><UpdateRuleActionResponse> <RequestId>9A2F243E-17FE-4874-QBB5-D02A25155AC8</RequestId> <Success>true</Success>

200 文档版本:20200417

Page 213: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

</UpdateRuleActionResponse>

1.1.2.11 消息通信

1.1.2.11.1 Pub调用该接口向指定Topic发布消息。

限制说明

不支持使用Pub接口来下发设置属性和调用服务的指令。设置属性,请

使用SetDeviceProperty或SetDevicesProperty;调用服务,请使

用InvokeThingService或InvokeThingsService。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:Pub。

ProductKey String 是 要发送消息产品Key。

TopicFullName

String 是 要接收消息的Topic,如/a1Q5XoY****/

device1/user/update。

说明:

• 不支持系统Topic。• 指定Topic的操作权限须为发布或发布和订

阅。

您可以调用QueryProductTopic接口查询产品

下的Topic类列表,或在设备详情页的Topic列

表页签下查看设备的具体Topic。

MessageContent

String 是 要发送的消息主体。您需要将消息原文转换成二进制数据,并进行Base64编码,从而生成消息主体。

文档版本:20200417 201

Page 214: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Qos Integer 否 指定消息的发送方式。取值:

0:最多发送一次。

1:最少发送一次。

如果不传入此参数,则使用默认值0。

说明:QoS=1的消息在物联网平台中最多可以保存7天。物联网平台不保存QoS=0的消息。

IotInstanceId String 否 共享实例用户不传此参数;仅独享实例用户需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

MessageId String 成功发送消息后,云端生成的消息ID,用于标识该消息。

示例

请求示例

返回示例

• JSON 格式

{ "RequestId":"BB71E443-4447-4024-A000-EDE09922891E", "Success":true, "MessageId":889455942124347329}

• XML格式

<?xml version="1.0" encoding="UTF-8"?> <PubResponse>

202 文档版本:20200417

Page 215: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

<RequestId>BB71E443-4447-4024-A000-EDE09922891E</RequestId> <Success>true</Success> <MessageId>889455942124347329</MessageId></PubResponse>

1.1.2.11.2 PubBroadcast调用该接口向订阅了指定Topic的所有设备发布广播消息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:PubBroadcast。

ProductKey String 是 要发送广播消息的产品Key。

TopicFullName

String 是 要接收广播消息的Topic全称。格式为:/

broadcast/${productKey}/自定义字段。其

中,${productKey}是要接收广播消息的具体产

品Key;自定义字段中您可以指定任意字段。

说明:

• 广播Topic是在设备开发时编码定义的,无

需控制台创建。

• 一个广播Topic最多可被1,000个设备订

阅。

如果您的设备超过数量限制,您可以对设

备进行分组。例如,如果您有5,000个设

备,您可以将设备按每组1,000个,而分成

5组。您需要分5次调用广播Topic,自定义

字段分别设置为group1/2/3/4/5,然后

让每组设备分别订阅各自分组的广播Topic

MessageContent

String 是 要发送的消息主体。您需要将消息原文转换成二进制数据,并进行Base64编码,从而生成消息主体。

IotInstanceId String 否 共享实例用户不传此参数;仅独享实例用户需传入实例ID。

公共请求参数 - 是 请参见公共参数。

文档版本:20200417 203

Page 216: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

MessageId String 成功发送消息后,云端生成的消息ID,用于标识该消息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"BB71E443-4447-4024-A000-EDE09922891E", "Success":true, }

• XML格式

<?xml version='1.0' encoding='UTF-8'?><PubBroadcastResponse> <RequestId>BB71E443-4447-4024-A000-EDE09922891E</RequestId> <Success>true</Success></PubBroadcastResponse>

1.1.2.11.3 RRpc调用该接口向指定设备发送请求消息,并同步返回响应。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:RRpc。

ProductKey String 是 要发送消息的产品Key。

DeviceName String 是 要接收消息的设备名称。

RequestBase64Byte

String 是 要发送的请求消息内容经过Base64编码得到的字符串格式数据。

204 文档版本:20200417

Page 217: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

Timeout Integer 是 等待设备回复消息的时间,单位是毫秒,取值范围是1,000 ~8,000。

Topic String 否 使用自定义的RRPC相关Topic。需要设备端配合使用,请参见设备端开发 《用户指南》 中消息通信 > MQTT同步通信(RRPC) > 调用自定义Topic。

不传入此参数,则使用系统默认的RRPC

Topic。

IotInstanceId String 否 共享实例用户不传此参数;仅独享实例用户需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

MessageId String 成功发送请求消息后,云端生成的消息ID,用于标识该消息。

RrpcCode String 调用成功时,生成的调用返回码,标识请求状

态。取值:

UNKNOWN:系统异常

SUCCESS:成功

TIMEOUT:设备响应超时

OFFLINE:设备离线

HALFCONN:设备离线(设备连接断开,但是断

开时间未超过一个心跳周期)

PayloadBase64Byte String 设备返回结果Base64编码后的值。

文档版本:20200417 205

Page 218: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"41C4265E-F05D-4E2E-AB09-E031F501AF7F", "Success":true, "RrpcCode":"SUCCESS", "PayloadBase64Byte":"d29ybGQgaGVsbG8=" "MessageId":889455942124347392 }

• XML格式

<?xml version='1.0' encoding='UTF-8'?><RRpcResponse> <RequestId>41C4265E-F05D-4E2E-AB09-E031F501AF7F<RequestId/> <Success>true</Success> <RrpcCode>SUCCESS</RrpcCode> <PayloadBase64Byte>d29ybGQgaGVsbG8=</PayloadBase64Byte> <MessageId>889455942124347392</MessageId></RRpcResponse>

1.1.2.12 设备影子

1.1.2.12.1 GetDeviceShadow调用该接口查询指定设备的影子信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:GetDeviceShadow。

ProductKey String 是 要查询的设备所隶属的产品Key。

DeviceName String 是 要查询的设备名称。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

返回参数

名称 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

206 文档版本:20200417

Page 219: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 描述

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

ShadowMessage

String 调用成功时,返回的设备影子信息。

说明:根据影子设备的不同状态,查询到的影子信息结构有所差别,详情请参考 《用户指南》 中设备管理 > 设备影子中的章节。

示例

请求示例

返回示例

• JSON格式

{ "RequestId":"BB71E443-4447-4024-A000-EDE09922891E", "Success":true, "ShadowMessage":{"method":"update","state":{"desired":{"color":"green"},"reported":"\"},"version":1} }

• XML格式

<?xml version='1.0' encoding='UTF-8'?><GetDeviceShadowResponse> <RequestId>BB71E443-4447-4024-A000-EDE09922891E</RequestId> <Success>true</Success> <ShadowMessage>{"method":"update","state":{"desired":{"color":"green"},"reported":"\"},"version":1}</ShadowMessage></GetDeviceShadowResponse>

1.1.2.12.2 UpdateDeviceShadow调用该接口修改指定设备的影子信息。

请求参数

名称 类型 是否必需 描述

Action String 是 要执行的操作,取值:UpdateDeviceShadow。

ProductKey String 是 要修改影子信息的设备所隶属的产品Key。

DeviceName String 是 要修改影子信息的设备名称。

文档版本:20200417 207

Page 220: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名称 类型 是否必需 描述

ShadowMessage

String 是 修改后的设备影子信息。示例如下:

{"method": "update","state": {"desired": {"color": "green"}}, "version": 2}

详情参见下表ShadowMessage。

IotInstanceId String 否 公共实例不传此参数;仅独享实例需传入实例ID。

公共请求参数 - 是 请参见公共参数。

表 1-75: ShadowMessage

名称 类型 是否必需 描述

method String 是 指定操作类型,取值:update。

state String 是 设备发送给shadow的具体状态。其中,desired部分是期望的影子状态。

version String 是 设备影子的版本,必须大于当前影子版本。

返回参数

参数 类型 描述

RequestId String 阿里云为该请求生成的唯一标识符。

Success Boolean 表示是否调用成功。true表示调用成功,false表示调用失败。

ErrorMessage String 调用失败时,返回的出错信息。

Code String 调用失败时,返回的错误码。错误码详情,请参见错误码。

示例

请求示例

返回示例

208 文档版本:20200417

Page 221: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• JSON格式

{ "RequestId":"BB71E443-4447-4024-A000-EDE09922891E", "Success":true,}

• XML格式

<?xml version='1.0' encoding='UTF-8'?><UpdateDeviceShadowResponse> <RequestId>BB71E443-4447-4024-A000-EDE09922891E</RequestId> <Success>true</Success></UpdateDeviceShadowResponse>

1.2 设备端开发指南

1.2.1 C SDK

1.2.1.1 SDK获取C语言Link Kit SDK适用于使用C语言开发业务处理逻辑的设备,由于C语言运行速度快、需要的运行

内存较少,目前大多数的IoT设备使用C语言进行产品开发。

重要通知:生活物联网平台推出了专有的设备端SDK,针对生活场景增加了一些新的功能,若产品接

入物联网平台请参照生活物联网平台的开发文档进行SDK获取以及产品开发。

SDK获取

SDK 3.X

• 稳定版本:3.0.1 (推荐)

• 最新版本:3.1.0 (支持X.509认证)

注:

• SDK 2.3.0版本SDK的开发文档可以通过此处访问

• 用户如果正在使用SDK2.3.0开发产品,并且想升级到SDK3.0.1,可以查看版本变更记录

历史版本

SDK使用说明

SDK提供了API供设备厂商调用,用于实现与阿里云IoT平台通信以及一些其它的辅助功能,例如WiFi

配网、本地控制等。

文档版本:20200417 209

Page 222: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

另外,C语言版本的SDK被设计为可以在不同的操作系统上运行,例如Linux、FreeRTOS、Windows

,因此SDK需要OS或者硬件支持的操作被定义为一些HAL函数,设备厂商在使用SDK开发产品时需要

将这些HAL函数进行实现。

产品的业务逻辑、SDK、HAL的关系如下图所

示:

其中产品业务逻辑和HAL需要设备厂商实现,SDK的目录wrappers\os下提供了针对Linux、

FreeRTOS的部分HAL参考实现供参考。

对于初次接触阿里云IoT的用户,请单击《快速体验》了解如何在Ubuntu上将一个模拟设备接入阿里

云IoT,从而理解一些基本的概念。

设备接入引导

SDK裁剪

• 如果您的产品基于嵌入式Linux进行开发,请单击《基于Make的编译说明》和《交叉编译示例》

了解如何进行SDK裁剪和开发

• 如果您的产品基于KEIL、IAR等开发工具进行开发,请单击《基于代码抽取的移植说明》了解如何

进行SDK裁剪、移植

MCU上集成SDK

如果您的产品使用MCU外接一个WiFi模组、2/3/4G、NB-IoT移动通信模组与互联网进行通信,并且

您的产品业务需要在MCU上实现:

210 文档版本:20200417

Page 223: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 如果外接模组支持MQTT协议,请参见《MCU+支持MQTT的模组》了解移植过程

• 如果外接模组模组不支持MQTT、但是支持TCP协议,请参见《MCU+支持TCP的模组》了解移植过

模组/SOC上集成SDK

如果您是模组商,或者是在一个支持TCP/IP的SOC上集成SDK,那么:

如果模组/SOC支持MQTT,请参见《在支持MQTT的模组上集成SDK》如果模组/SOC不支持MQTT但

是支持TCP,请参见《在支持TCP的模组上集成SDK》

SDK功能列表

下面的表格列出了目前最新版本C Link Kit SDK的功能:

功能模块 功能点

设备连云 • MQTT连云,设备可通过MQTT与阿里云IoT物联网平台通信• CoAP连云,设备可通过CoAP与阿里云IoT物联网平台通信,用于设

备主动上报信息的场景• HTTPS连云,设备可通过HTTPS与阿里云IoT物联网平台通信,用于

设备主动上报信息的场景

设备身份认证 • 一机一密• 一型一密

物模型 使用属性、服务、事件对设备进行描述以及实现,包括:

• 属性上报、设置• 服务调用• 事件上报

云端region设置 • 厂商指定region,告知设备连接到阿里云的具体的云端站点,例如中国上海、新加坡、美国、法国

• 动态连云,设备自动连接到距离设备延时最短的云端站点

OTA 设备固件升级

远程配置 设备配置文件获取

子设备管理 用于让网关设备添加、删除子设备,以及对子设备进行控制

WiFi配网 将WiFi热点的SSID/密码传输给WiFi设备,包括:

• 一键配网• 手机热点配网• 设备热点配网• 零配

文档版本:20200417 211

Page 224: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

功能模块 功能点

设备本地控制 局域网内,通过CoAP协议对设备进行控制,包括:ALCS Server,被控端实现ALCS Client,控制端实现,通常被希望通过本地控制设备的网关使用

设备绑定支持 设备绑定token维护,设备通过WiFI、以太网接入,并且通过阿里云开放智能生活平台管理时使用

设备影子 在云端存储设备指定信息供APP查询,避免总是从设备获取信息引入的延时

Reset支持 当设备执行Factory Reset时,通知云端清除记录。例如清除设备与用户的绑定关系,清除网关与子设备的关联关系等。

时间获取 从阿里云物联网平台获取当前最新的时间

文件上传 通过HTTP2上传文件

说明:

注:表格中并没有对每种功能给出详细描述,在相应功能的开发章节中会对每个功能进行详细描

述。

历史版本清单

版本号 发布日期 下载链接 更新内容

3.1.0 2019/10/18 sdk下载 • 对关键过程增加状态码机制• WiFi配网增强,解决AP Isolation

、移除路由器配网方案、新增Linux平台的配网HAL函数参考代码

• 增加对X.509的支持• OTA新增断点续传• 子设备管理新增子设备/网关多对多

拓扑关系• 系统topic订阅优化,缩短订阅时间

3.0.1 2019/03/15 sdk下载 • 新增对异步/通知式的底层TCP/IP协议栈的支持

• 支持将选中功能对应的代码抽取出来,方便快速将SDK放入客户的编译环境进行编译

• 代码抽取时自动生成客户HAL适配文件

• 新增http2文件上传功能• 配网增加设备热度配网方案

212 文档版本:20200417

Page 225: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

版本号 发布日期 下载链接 更新内容

2.3.0 2018/11/19 sdk下载 • 新增一套物模型编程接口:风格为IOT_Linkkit_XXX(), 旧版接口linkkit_xxx()仍然保留

• 新增图形化配置方式支持• WiFi配网的四种模式可以分离

2.2.1 2019/09/03 sdk下载 • 新增一型一密/动态注册功能• 新增OTA使用iTLS下载固件功能• WiFi配网功能开源发布• 本地控制功能开源发布

2.2.0 2018/08/06 sdk下载 • 离线reset支持• 简化版TSL支持• 设备禁用/使能支持• TSL数组支持object类型• MQTT海外多站点连接支持• itls支持

2.1.0 2018/03/20 sdk下载 • 新增cmake编译系统• 增加物模型支持

2.0.3 2018/01/31 sdk下载 • 子设备管理支持• 优化tls,修复内存泄露• 升级MQTT通道,支持更长的topic

、支持更多的订阅请求、MQTT支持多线程

2.0.2 2017/11/30 sdk下载 • 新增mbedtls支持,目前适配Linux和Windows系统

• 优化HTTP接口,支持发送报文时不断开TLS连接

• 新增OpenSSL适配• 支持用mingw32编译Win7的库和

例程• make reconfig可弹出和选择已适

配平台

文档版本:20200417 213

Page 226: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

版本号 发布日期 下载链接 更新内容

2.0.1 2017/10/10 sdk下载 • 新增基于CoAP通知方式的OTA• 增加HTTP+TLS的云端连接通道• 细化OTA状态• 修正SDK在armcc编译器编译时出

现的报错

2.0.0 2017/08/21 sdk下载 • 新增MQTT直连• 新增CoAP通道• 增加OTA功能• 升级构建系统

1.2.1.2 快速体验本章描述如何在Ubuntu上通过MQTT topic和通过物模型的编程方式,上报和接收业务报文。这个环

节使用Ubuntu主机模拟IoT设备,让用户体验设备如何与阿里云物联网平台连接和交互,基于Link

Kit SDK3.0.1进行编写。

安装本地开发环境

• 通过Ubuntu系统进行开发

1. 安装Ubuntu16.04

本文编写是对照的编译环境是64位主机上的Ubuntu16.04,在其它Linux版本上尚未验证

过,推荐安装与阿里一致的发行版以避免碰到兼容性方面的问题。

然后安装64位的Desktop版本的Ubuntu 16.04.x LTS,下载地址:http://releases.ubuntu.

com/16.04。

如果您使用Windows操作系统,可以安装虚拟机软件Virtualbox获得Linux开发环境,下载地

址:https://www.virtualbox.org/wiki/Downloads。

2. 安装必备软件

本SDK的开发编译环境使用如下软件:make-4.1, git-2.7.4, gcc-5.4.0, gcov-5.4.0, lcov-1.

12, bash-4.3.48, tar-1.28, mingw-5.3.1

可使用如下命令行安装必要的软件:

$ sudo apt-get install -y build-essential make git gcc

• 通过Hacklab Web IDE进行开发

如果您不打算在您的PC或者笔记本电脑上安装Ubuntu,也可通过阿里云IoT提供的Hacklab Web

IDE环境直接进行设备开发。Hacklab Web IDE是一个云端的Linux开发环境,已经将必要的

214 文档版本:20200417

Page 227: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

软件安装完毕,只要您拥有一个阿里云账号,就可以通过浏览器登录进行开发,单击此处登录

Hacklab Web IDE。

以MQTT Topic编程方式接入设备

1. 创建产品和设备

请登录阿里云IoT物联网平台进行产品创建,登录时通过您的阿里云账号进行登录。因为是直接通

过MQTT的Topic进行产品功能实现,所以在创建产品时选择“基础版”即可。

创建产品之后可以添加一个具体的设备,阿里云IoT物联网平台会为设备生成身份信息。

如果您对云端如何创建产品不熟悉,请单击此处了解如何在阿里云IoT物联网平台进行产品和设备

创建。

2. 产品功能实现

a. 了解SDK根目录结构

获取Linkkit SDK后,顶层目录结构如下:

$ lscerts config.bat external_libs extract.bat extract.sh LICENSE makefile make.settings model.json README.md src tools wrappers

b. 配置SDK

SDK默认配置打开了物模型选项,这里仅演示基础版的使用,先关闭物模型选项。

$ make menuconfig

c. 填写设备三元组到例程中

设备开发者需要实现SDK定义的相应HAL函数获取设备的身份信息,由于本文使用Ubuntu来模

拟IoT设备,因此打开文件 wrappers/os/ubuntu/HAL_OS_linux.c,编辑如下代码片段,填

入之前在物联网平台创建产品和设备后得到的设备身份信息:

• ProductKey:产品唯一标识

• ProductSecret:产品密钥

• DeviceName:设备唯一标识

• DeviceSecret:设备密钥

#ifdef DYNAMIC_REGISTER......#else#ifdef DEVICE_MODEL_ENABLED......

文档版本:20200417 215

Page 228: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

#elsechar _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "xxxx"; /*使用实际的product key替换*/char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "yyyy"; /*使用实际的product secret替换*/char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "zzzz"; /*使用实际的device name 替换*/char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "ssss"; /*使用device secret替换*/#endif#endif

说明:

请在物联网平台的管理控制台将topic/${productKey}/${deviceName}/get设置为“可订阅

可发布”权限,下面的代码中将会用到。

d. 初始化与建立连接

下面的代码片段来自MQTT上云功能的例程 src/mqtt/examples/mqtt_example.c, 它简单描

述了设备的初始化以及连接过程。

定制化MQTT参数。

iotx_mqtt_param_t mqtt_params;

memset(&mqtt_params, 0x0, sizeof(mqtt_params));

/* mqtt_params.request_timeout_ms = 2000; *//* mqtt_params.clean_session = 0; *//* mqtt_params.keepalive_interval_ms = 60000; *//* mqtt_params.write_buf_size = 1024; *//* mqtt_params.read_buf_size = 1024; */mqtt_params.handle_event.h_fp = example_event_handle;

说明:

上面的代码中注释掉的地方是mqtt相关配置的默认数值,用户可以不用赋值,SDK会自动填

写默认值。如果用户希望调整默认的连接参数,只需要去掉相应的注释,并填入数值即可。

尝试建立与服务器的MQTT连接。

pclient = IOT_MQTT_Construct(&mqtt_params);if (NULL == pclient) { EXAMPLE_TRACE("MQTT construct failed"); return -1;}

说明:

216 文档版本:20200417

Page 229: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

将连接参数结构体传参给IOT_MQTT_Construct()接口,即可触发MQTT连接建立的动作成功

返回非空值作为已建立连接的句柄,失败则返回空。

e. 上报数据到云端

在示例文件中定义了如下的topic。

/${productKey}/${deviceName}/get

下面的代码片段示例了如何向这个Topic发送数据。

int example_publish(void *handle){ int res = 0; const char *fmt = "/%s/%s/get"; char *topic = NULL; int topic_len = 0; char *payload = "{\"message\":\"hello!\"}";

topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1; topic = HAL_Malloc(topic_len); if (topic == NULL) { EXAMPLE_TRACE("memory not enough"); return -1; } memset(topic, 0, topic_len); HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);

res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, strlen(payload));

说明:

其中,IOT_MQTT_Publish_Simple()的第1个参数可以填入之前调用IOT_MQTT_Construct

()得到的句柄返回值,也可以直接填入0, 代表告诉SDK,使用当前已建立的唯一MQTT连接来

发送消息。

f. 从云端订阅并处理数据

说明:

示例程序为了尽量简单的演示发布/订阅,代码中对topic/${productKey}/${deviceName}/

get进行了订阅,意味着设备发送给物联网平台的数据将会被物联网平台发送回设备。

下面的代码订阅指定的topic并指定接收到数据时的处理函数。

res = example_subscribe(pclient);if (res < 0) { IOT_MQTT_Destroy(&pclient); return -1;}

文档版本:20200417 217

Page 230: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

...

...

int example_subscribe(void *handle){ ... res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL); ...

说明:

其中,IOT_MQTT_Subscribe()的第1个参数可以填入之前调用IOT_MQTT_Construct()得到

的句柄返回值,也可以直接填入0, 代表告诉SDK,使用当前已建立的唯一MQTT连接来订

阅Topic。

示例程序中收到来自云端消息,在回调函数中处理时只是把消息打印出来。

void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg){ iotx_mqtt_topic_info_t *topic_info = (iotx_mqtt_topic_info_pt) msg->msg;

switch (msg->event_type) { case IOTX_MQTT_EVENT_PUBLISH_RECEIVED: /* print topic name and topic message */ EXAMPLE_TRACE("Message Arrived:"); EXAMPLE_TRACE("Topic : %.*s", topic_info->topic_len, topic_info->ptopic); EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload); EXAMPLE_TRACE("\n"); break; default: break; }}

示例代码向该Topic周期性的发送数据,用户在实现自己的产品逻辑时不需要周期的发送数

据,只是有需要上报的时候再发送数据。

while (1) { if (0 == loop_cnt % 20) { example_publish(pclient); }

IOT_MQTT_Yield(pclient, 200);

loop_cnt += 1;}

218 文档版本:20200417

Page 231: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

g. 编译例子程序

在SDK顶层目录运行如下命令:

make distcleanmake

编译成功完成后,生成的样例程序在当前路径的output/release/bin目录下:

$ tree output/releaseoutput/release/+-- bin......| +-- mqtt-example......

3. 观察数据

执行如下命令:

$ ./output/release/bin/mqtt-example

可以在物联网平台的控制台,找到指定的产品,在其日志服务中查看设备上报的消息。可以单击

此处了解如何在云端查看设备上报的数据。

在Linux的console里面也可以看见示例程序打印的来自云端的数据:

example_message_arrive|031 :: Message Arrived:example_message_arrive|032 :: Topic : /a1MZxOdcBnO/test_01/getexample_message_arrive|033 :: Payload: {"message":"hello!"}example_message_arrive|034 ::

文档版本:20200417 219

Page 232: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

以物模型编程方式接入设备

1. 创建产品和设备

可以在阿里云IoT物联网平台以及其上承载的多个行业服务中进行产品的创建,下面是在阿里

云IoT物联网平台创建产品的帮助链接。

• 如何创建支持物模型的产品

• 如何定义物模型

若产品需要在生活物联网平台(注:基于阿里云IoT物联网平台创建的针对生活场景的行业服

务)进行创建,可以登录生活物联网平台创建产品。

本示例产品的物模型描述文件model_for_examples.JSON存放在./src/dev_model/examples

/目录下,为了简化用户在物联网平台控制台上的操作,用户可以在控制台创建自己的产品后,将

该文件中的productkey替换为自己创建产品的productKey,然后在 产品详情 - 功能定义 页面单

击 导入物模型 按钮将该JSON文件导入到自己创建的产品中,这样用户的产品将具备示例产品的

全部物模型定义。

2. 产品功能实现

a. 填写设备身份信息到例程中。

设备的身份信息通过HAL调用返回给SDK,由于本体验基于Linux,因此相关的HAL实现位于

wrappers/os/ubuntu/HAL_OS_linux.c,用户需要把文件中的以下设备身份信息替换成自己

创建的设备的身份信息。

#ifdef DEVICE_MODEL_ENABLEDchar _product_key[IOTX_PRODUCT_KEY_LEN + 1] = "a1RIsMLz2BJ";char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "fSAF0hle6xL0oRWd";char _device_name[IOTX_DEVICE_NAME_LEN + 1] = "example1";char _device_secret[IOTX_DEVICE_SECRET_LEN + 1] = "RDXf67itLqZCwdMCRrw0N5FHbv5D7jrE";

说明:

用户也可以不用修改这些全局变量,而是直接修改HAL_GetProductKey()等函数返回设备身

份信息。

b. 编译与运行程序。

在SDK顶层目录执行如下命令。

$ make distclean$ make

220 文档版本:20200417

Page 233: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

编译成功完成后,生成的高级版例子程序在当前路径的output/release/bin目录下,名为

linkkit-example-solo。

在SDK顶层目录执行如下命令。

$ ./output/release/bin/linkkit-example-solo

3. 观察数据

示例程序会定期将Counter属性的数值上报云端,因此可以在云端查看收到的属性。用户可以将

该属性配置为可读写属性,并且可以在云端对该属性进行设置,然后再次查看从设备端上报的

Counter值。

• 属性上报

示例中使用__user_post_property__作为上报属性的例子。该示例会循环上报各种情况

的payload,用户可观察在上报错误payload时返回的提示信息。

代码中上报属性的代码片段如下。

/* Post Proprety Example */if (time_now_sec % 11 == 0 && user_master_dev_available()) { user_post_property();}

观察属性上报示例函数。

void user_post_property(void){ static int example_index = 0; int res = 0; user_example_ctx_t *user_example_ctx = user_example_get_ctx(); char *property_payload = "NULL";

if (example_index == 0) {

正常上报属性的情况。

void user_post_property(void){ static int cnt = 0; int res = 0;

char property_payload[30] = {0}; HAL_Snprintf(property_payload, sizeof(property_payload), "{\"Counter\": %d}", cnt++);

res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY, (unsigned char *)property_payload, strlen(property_payload));

文档版本:20200417 221

Page 234: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

EXAMPLE_TRACE("Post Property Message ID: %d", res);}

下面是上报正常属性时的日志。

[inf] dm_msg_request(205): DM Send Message, URI: /sys/a1X2bEnP82z/test_06/thing/event/property/post, Payload: {"id":"2","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}[inf] MQTTPublish(2546): Upstream Topic: '/sys/a1X2bEnP82z/test_06/thing/event/property/post'

这里是发送给云端的消息。

> {> "id": "2",> "version": "1.0",> "params": {> "Counter": 1> },> "method": "thing.event.property.post"> }

收到的云端应答。

< {< "code": 200,< "data": {< },< "id": "1",< "message": "success",< "method": "thing.event.property.post",< "version": "1.0"< }

用户回调函数的日志。

user_report_reply_event_handler.314: Message Post Reply Received, Devid: 0, Message ID: 2, Code: 200, Reply: {}

• 属性设置处理

收到属性set请求时,会进入如下回调函数。

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);

222 文档版本:20200417

Page 235: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

将属性设置的执行结果发回云端,更新云端设备属性。

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

return 0;}

日志中可以看到从服务端下来的属性设置消息。

[dbg] iotx_mc_cycle(1774): PUBLISH[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/property/set'[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

从云端收到的属性设置报文内容。

< {< "method": "thing.service.property.set",< "id": "161430786",< "params": {< "LightSwitch": 1< },< "version": "1.0.0"< }

发送回云端的应答消息。

> {> "id": "161430786",> "code": 200,> "data": {> }> }

[inf] dm_client_publish(106): Publish Result: 0[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 15[inf] _iotx_linkkit_event_callback(221): Receive Message: {"devid":0,"payload":{"LightSwitch":1}}[dbg] _iotx_linkkit_event_callback(339): Current Devid: 0[dbg] _iotx_linkkit_event_callback(340): Current Payload: {"LightSwitch":1}

user_property_set_event_handler() 示例回调函数中收到属性设置的日志。

user_property_set_event_handler.160: Property Set Received, Devid: 0, Request: {"LightSwitch":1}

文档版本:20200417 223

Page 236: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

这样,一条从服务端设置属性的命令就到达设备端并执行完毕了。

最后收到的对属性上报的应答。

< {< "code": 200,< "data": {< },< "id": "2",< "message": "success",< "method": "thing.event.property.post",< "version": "1.0"< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555): Packet Ident : 00000000[dbg] iotx_mc_handle_recv_PUBLISH(1556): Topic Length : 60[dbg] iotx_mc_handle_recv_PUBLISH(1560): Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply[dbg] iotx_mc_handle_recv_PUBLISH(1563): Payload Len/Room : 104 / 4935[dbg] iotx_mc_handle_recv_PUBLISH(1564): Receive Buflen : 5000[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...[dbg] iotx_mc_deliver_message(1291): topic be matched[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: property[dbg] dm_msg_response_parse(167): Current Request Message ID: 2[dbg] dm_msg_response_parse(168): Current Request Message Code: 200[dbg] dm_msg_response_parse(169): Current Request Message Data: {}[dbg] dm_msg_response_parse(174): Current Request Message Desc: success[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50[dbg] dm_msg_cache_remove(142): Remove Message ID: 2[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 30[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":2,"code":200,"devid":0,"payload":{}}[dbg] _iotx_linkkit_event_callback(476): Current Id: 2[dbg] _iotx_linkkit_event_callback(477): Current Code: 200[dbg] _iotx_linkkit_event_callback(478): Current Devid: 0user_report_reply_event_handler.300: Message Post Reply Received, Devid: 0, Message ID: 2, Code: 200, Reply: {}

说明:

实际的产品收到属性设置时,应该解析属性并进行相应处理而不是仅仅将数值发送回云端。

• 事件上报

示例中使用IOT_Linkkit_TriggerEvent上报属性。该示例会循环上报各种情况的payload,用

户可观察在上报错误payload时返回的提示信息。

正常上报事件的情况。

void user_post_event(void){ int res = 0; char *event_id = "HardwareError"; char *event_payload = "{\"ErrorCode\": 0}";

224 文档版本:20200417

Page 237: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

res = IOT_Linkkit_TriggerEvent(EXAMPLE_MASTER_DEVID, event_id, strlen(event_id), event_payload, strlen(event_payload)); EXAMPLE_TRACE("Post Event Message ID: %d", res);}

示例程序中Error事件(Event)是约每10s上报一次,在以上各种情况中循环。其中正常上报

的日志如下。

[inf] dm_msg_request(218): DM Send Message, URI: /sys/a1csED27mp7/AdvExample1/thing/event/HardwareError/post, Payload: {"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.HardwareError.post"}[dbg] MQTTPublish(319): ALLOC: (136) / [200] @ 0x1195150[inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/HardwareError/post'[inf] MQTTPublish(379): Upstream Payload:

向云端上报的事件消息内容及日志。

> {> "id": "1",> "version": "1.0",> "params": {> "ErrorCode": 0> },> "method": "thing.event.HardwareError.post"> }

[inf] dm_client_publish(106): Publish Result: 0[dbg] alcs_observe_notify(105): payload:{"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.Error.post"}[inf] dm_server_send(76): Send Observe Notify Result 0[dbg] dm_msg_cache_insert(79): dmc list size: 0user_post_event.470: Post Event Message ID: 1[dbg] iotx_mc_cycle(1774): PUBLISH[inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/HardwareError/post_reply'[inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:

从云端收到的应答消息内容及日志。

< {< "code": 200,< "data": {< },< "id": "1",< "message": "success",< "method": "thing.event.HardwareError.post",< "version": "1.0"< }

[dbg] iotx_mc_handle_recv_PUBLISH(1555): Packet Ident : 00000000[dbg] iotx_mc_handle_recv_PUBLISH(1556): Topic Length : 57[dbg] iotx_mc_handle_recv_PUBLISH(1560): Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/Error/post_reply[dbg] iotx_mc_handle_recv_PUBLISH(1563): Payload Len/Room : 101 / 4938[dbg] iotx_mc_handle_recv_PUBLISH(1564): Receive Buflen : 5000

文档版本:20200417 225

Page 238: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

[dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...[dbg] iotx_mc_deliver_message(1291): topic be matched[inf] dm_msg_proc_thing_event_post_reply(258): Event Id: Error[dbg] dm_msg_response_parse(167): Current Request Message ID: 1[dbg] dm_msg_response_parse(168): Current Request Message Code: 200[dbg] dm_msg_response_parse(169): Current Request Message Data: {}[dbg] dm_msg_response_parse(174): Current Request Message Desc: success[dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50[dbg] dm_msg_cache_remove(142): Remove Message ID: 1[inf] _iotx_linkkit_event_callback(219): Receive Message Type: 31[inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":1,"code":200,"devid":0,"eventid":"Error","payload":"success"}[dbg] _iotx_linkkit_event_callback(513): Current Id: 1[dbg] _iotx_linkkit_event_callback(514): Current Code: 200[dbg] _iotx_linkkit_event_callback(515): Current Devid: 0[dbg] _iotx_linkkit_event_callback(516): Current EventID: Error[dbg] _iotx_linkkit_event_callback(517): Current Message: success

用户回调函数user_trigger_event_reply_event_handler()中的日志。

user_trigger_event_reply_event_handler.310: Trigger Event Reply Received, Devid: 0, Message ID: 1, Code: 200, EventID: Error, Message: success

• 服务调用

注册服务消息的处理函数。

IOT_RegisterCallback(ITE_SERVICE_REQUEST, user_service_request_event_handler);

收到服务请求消息时,会进入下面的回调函数。设备端演示了一个简单的加法运算服务,入参

为NumberA和NumberB,出参为Result,例程中使用cJSON解析属性的值。

static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len, const char *request, const int request_len, char **response, int *response_len){ int add_result = 0; cJSON *root = NULL, *item_number_a = NULL, *item_number_b = NULL; const char *response_fmt = "{\"Result\": %d}";

EXAMPLE_TRACE("Service Request Received, Service ID: %.*s, Payload: %s", serviceid_len, serviceid, request);

/* Parse Root */ root = cJSON_Parse(request); if (root == NULL || !cJSON_IsObject(root)) { EXAMPLE_TRACE("JSON Parse Error"); return -1; }

if (strlen("Operation_Service") == serviceid_len && memcmp("Operation_Service", serviceid, serviceid_len) == 0) { /* Parse NumberA */ item_number_a = cJSON_GetObjectItem(root, "NumberA"); if (item_number_a == NULL || !cJSON_IsNumber(item_number_a)) { cJSON_Delete(root);

226 文档版本:20200417

Page 239: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

return -1; } EXAMPLE_TRACE("NumberA = %d", item_number_a->valueint);

/* Parse NumberB */ item_number_b = cJSON_GetObjectItem(root, "NumberB"); if (item_number_b == NULL || !cJSON_IsNumber(item_number_b)) { cJSON_Delete(root); return -1; } EXAMPLE_TRACE("NumberB = %d", item_number_b->valueint);

add_result = item_number_a->valueint + item_number_b->valueint;

/* Send Service Response To Cloud */ *response_len = strlen(response_fmt) + 10 + 1; *response = (char *)HAL_Malloc(*response_len); if (*response == NULL) { EXAMPLE_TRACE("Memory Not Enough"); return -1; } memset(*response, 0, *response_len); HAL_Snprintf(*response, *response_len, response_fmt, add_result); *response_len = strlen(*response); }

cJSON_Delete(root); return 0;}

此时在设备端可以看到如下日志。

收到的云端的服务调用,输入参数为NumberA(值为1),NumberB(值为2)。

< {< "method": "thing.service.Operation_Service",< "id": "280532170",< "params": {< "NumberB": 2,< "NumberA": 1< },< "version": "1.0.0"< }

在回调函数中将NumberA和NumberB的值相加后赋值给Result后,上报到云端。

> {> "id": "280532170",> "code": 200,> "data": {> "Result": 3> }> }

关于高级版单品例程中服务/属性/事件的说明就此结束。

文档版本:20200417 227

Page 240: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.3 版本变动记录++V3.0.1版本最大的变化, 在于不强制用户使用SDK自带的编译系统, 而是可以按需抽取部分功能点对

应的C文件, 以自己喜欢的任何方式进行编译++

V3.0.1

V3.0.1版本在2019年03月发布, 相对2018年11月发布的V2.3.0版本有如下更动

新增支持源代码方式移植

• 适用于安装了 Ubuntu16.04 64位 的主机,或者安装了 Windows XP, Windows7, Windows10

的主机进行开发

• 用户可以通过 make menuconfig 命令(Ubuntu)或者通过点击 config.bat 脚本(Windows)来选

择功能点

• 选好功能点之后, 都可以通过 extract.sh 命令(Ubuntu)或者是通过点击 extract.bat 脚

本(Windows) 来抽取需要的源文件

• 有了这些源文件, 不论用户在什么主机上用什么方式开发, 都可以方便的将这些文件加入自己的工

程中, 用自己熟悉的源码编译方式进行编译

在这个过程中, 所有需要用户实现的HAL函数接口都被自动整理到一个单独的文件中, 位于 output/

eng/wrappers/wrapper.c, 用户需要对这些函数进行实现

++这项增强颠覆性的解决了过去如果用户不不能很顺利的交叉编译SDK, 就会卡住无法继续的问题, 大

幅增强SDK的可移植性和易用性++

*注: 原有的编译系统和使用方式仍然存在, 详情可见文档: *基于Make的编译系统说明

目录结构

• 为增强易用性, V3.0.1版本的SDK采用了扁平化的目录结构摆放源码, 例如 src/mqtt 下集中摆放所

有MQTT上云功能点的H文件和C文件, 所有的 src/xxxx 目录都是内聚的

• 所有源文件的摆放和SDK的功能点形成一一对应的关系, 除了表示基础的 src/infra 目录, 现在所有

的 src/xxx 都各自对应一个SDK的功能, 有几个 src/xxx, 就有几个功能点, 例如

- src/dynamic_register: 摆放一型一密/动态注册相关的所有源文件

- src/dev_sign: 摆放设备签名相关的所有源文件

- src/mqtt: 摆放MQTT连云相关的所有源文件

- src/ota: 摆放OTA固件下载相关的所有源文件

- src/dev_model: 摆放物模型管理/子设备管理相关的所有源文件

228 文档版本:20200417

Page 241: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API接口和HAL接口的呈现方式

过去SDK只有2个全局性的头文件 iot_import.h 和 iot_export.h, 分别列出SDK对外界需要依赖的

HAL_XXX() 底层接口和列出SDK对外界提供的 IOT_XXX 用户接口

我们得到部分用户的反馈, iot_import.h 中列出的100多个HAL接口使他们误以为全都需要对接,

iot_export.h 中列出的200多个API接口使他们误以为全部需要学习使用, 感到负担很重

因此, 我们去掉了这种设计

• SDK不再有一个整体性的 iot_import.h 和 iot_export.h

• 也不再有顶级目录下的 include

• 而是将源文件严格按所归属的功能点目录分散排布, 我们尽量避免让用户看到他其实不需要关注的

部分

++现在++

• 使用V3.0.1版本的SDK, 用户首先要了解SDK提供了哪些功能点(例如MQTT连云, OTA下载等), 并确

定自己需要这些功能中的哪一些, 并图形化的配置和选中它们

• 其次, 通过抽取工具(在Ubuntu主机上是 extract.sh 脚本, 在Windows主机上是 extract.bat) 得到

output 目录下这些功能对应的源文件

• 接着便可以使用, 在使用环节, 我们对SDK所有外部接口的呈现方式遵循如下的设计原则

- output/eng/xxx 就对应名为 xxx 的功能点, 它们从 src/xxx 整理而来

- output/eng/xxx/xxx_api.h 就对应名为 xxx 的功能点提供的API用户接口, 它们从 src/xxx/

xxx_api.h 整理而来

- output/eng/wrappers/wrapper.c 自动产生并列出所有需要用户根据嵌入式目标平台实现的

HAL_XXX() 底层接口

• 也就是说

- 只有您需要的功能点, 才需要去看 src/xxx/xxx_api.h 或者 output/eng/xxx/xxx_api.h, 所以

确保用户不会看到多余的API接口声明

- 所有您需要实现的函数, 都列在 output/eng/wrappers/wrapper.c 中, 不需对接的不会包含

其中, 所以确保用户不会看到多余的HAL接口定义

举例来说, 在最简单的情形下, 用户只需要SDK中计算MQTT连云签名的能力, 由于这个能力由 src/

dev_sign 或者 output/eng/dev_sign 提供

• 用户只会看到1个API接口, 列在 dev_sign_api.h 中

• 用户不会看到任何HAL接口, 甚至也看不到 wrapper.c, 因为这个功能是零依赖的, 不需要用户实现

任何C函数即可使用

文档版本:20200417 229

Page 242: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

make.settings 文件

• 新增对使用 Windows XP, Windows 7 或者 Windows 10 主机做开发的用户, 也可以用 config.

bat 工具图形化的配置所需要的功能, 不一定需要 Linux 主机

• FEATURE_XXX 系列的选项名字修改

曾用名 新版名 说明

FEATURE_AWSS_SUPPORT_PHONEASAP

FEATURE_AWSS_SUPPORT_AHA

WiFi配网功能中的手机热点配网模式

FEATURE_AWSS_SUPPORT_ROUTER

FEATURE_AWSS_SUPPORT_ADHA

WiFi配网功能中的路由器配网模式

• 新增以下选项

- FEATURE_AWSS_SUPPORT_SMARTCONFIG_WPS: WiFi配网功能中的点对点配网模式

- FEATURE_AWSS_SUPPORT_DEV_AP: WiFi配网共中的设备热点配网模式

MQTT函数接口

• 不再需要调用 IOT_SetupConnInfo(), 用户建立MQTT连接只需要知道1个接口 IOT_MQTT_C

onstruct()

• 不再需要准备入参, 调用 IOT_MQTT_Construct() 的时候绝大多数连接参数都可以不填写, SDK会

自动补上默认值而不是报错返回, 详见 快速体验

新增的功能点和接口

• 新增设备签名功能点, 是SDK的最简形态

- 这个功能点只有1个API, 是 IOT_Sign_MQTT()

- 详见文档: 设备签名编程指南

• 新增一型一密功能点, 用于所有设备不必烧录不同三元组的场景

- 这个功能点只有1个API, 是 IOT_Dynamic_Register()

- 详见文档: 一型一密编程指南

• 新增设备重置功能点, 可用于设备告知云端解除绑定关系, 解除子设备和网关对应关系的场景

- 这个功能点只有1个API, 是 IOT_DevReset_Report()

- 详见文档: 设备重置编程指南

230 文档版本:20200417

Page 243: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 新增HTTP2文件上传功能点, 可用于流式上传大文件到云端的场景

- 这个功能点只有3个API, 是 IOT_HTTP2_UploadFile_Connect(), IOT_HTTP2_UploadFile

_Request() 和 IOT_HTTP2_UploadFile_Disconnect()

- 详见文档: HTTP2文件上传编程指南

去掉的功能

• 由于用户已可使用源文件方式移植或者GNU Make方式移植, 我们去掉了基于 cmake 的编译方式

支持

V2.3.0

V2.3.0版本在2018年11月发布, 相对2018年8月31日发布的V2.2.1版本有如下更动。

make.settings 文件

• 对使用 Ubuntu16.04 的 64位 主机开发的用户, 可以用 make menuconfig 命令图形化编辑

make.settings 文件

• FEATURE_XXX 系列的选项名字修改

曾用名 新版名 说明

FEATURE_SDK_ENHANCE FEATURE_DEVICE_MODEL_ENABLED

物模型管理(Alink JSON协议)能力开关

FEATURE_ENHANCED_GATEWAY

FEATURE_DEVICE_MODEL_GATEWAY

物模型管理中的网关能力开关

FEATURE_WIFI_AWSS_ENABLED

FEATURE_WIFI_PROVISION_ENABLED

WiFi配网能力开关

• 新增以下选项

- FEATURE_DEVICE_BIND_ENABLED: 设备绑定功能的开关, 只有连接飞燕平台的客户需要关注

并打开这个开关, 用于使能公版app控制设备

- FEATURE_ALCS_CLIENT_ENABLED: 本地通信中的客户端部分功能开关, 只有边缘网关这类需

要控制其他IoT设备的设备才需要打开

- FEATURE_ALCS_SERVER_ENABLED: 本地通信中的服务端部分功能开关, 需要接受手机app或

者边缘网关局域网控制的设备需要打开

- FEATURE_AWSS_SUPPORT_SMARTCONFIG: WiFi配网中的一键配网模式

- FEATURE_AWSS_SUPPORT_ZEROCONFIG: WiFi配网中的零配模式

- FEATURE_AWSS_SUPPORT_ROUTER: WiFi配网中的路由器配网模式

- FEATURE_AWSS_SUPPORT_PHONEASAP: WiFi配网中的手机热点配网模式

文档版本:20200417 231

Page 244: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 删除以下选项

- FEATURE_COAP_DTLS_SUPPORT: CoAP上云是否经过DTLS加密, 由于总是使能, 不再需要用

户配置

全局函数接口

• 删除 IOT_OpenLog() 和 IOT_CloseLog(), 用户可以通过 IOT_SetLogLevel() 来控制SDK打印日志

的详细程度或者不打印

• 删除 IOT_LOG_EMERG 这个日志等级, 改成 IOT_LOG_NONE, 用于 IOT_SetLogLevel(

IOT_LOG_NONE), 表达日志功能的整体关闭

• 删除 IOT_Linkkit_Ioctl(), 原有功能合并到 IOT_Ioctl()中, 所有的参数选项可查看 iotx_ioctl

_option_t 枚举定义

• 增强 IOT_Ioctl(), 新选项 IOTX_IOCTL_SET_MQTT_DOMAIN 和 IOTX_IOCTL_SET_HTTP_DOMAIN

可用于让客户传入自定义连接的MQTT/HTTP域名, 用于海外新站点

MQTT函数接口

• 原有基础版接口及新增接口中, 第1个参数handle都可以传NULL, 表示选取默认参数创建连接或使

用默认连接, 包括

- IOT_MQTT_Construct

- IOT_MQTT_Destroy

- IOT_MQTT_Yield

- IOT_MQTT_LogPost

- IOT_MQTT_CheckStateNormal

- IOT_MQTT_Subscribe

- IOT_MQTT_Unsubscribe

- IOT_MQTT_Publish

- IOT_MQTT_Subscribe_Sync

- IOT_MQTT_Publish_Simple

• 删除结构体 iotx_mqtt_param_t 中的 pwrite_buf 成员和 pread_buf 成员

• 新增接口 IOT_MQTT_Publish_Simple(), 可以传入字符串类型的参数表达topic和payload

int IOT_MQTT_Publish_Simple(void *handle, const char *topic_name, int qos, void *data, int len);

• 新增接口 IOT_MQTT_Subscribe_Sync(), 可以阻塞式的进行同步订阅, 订阅成功之前函数并不返回

int IOT_MQTT_Subscribe_Sync(void *handle, const char *topic_filter,

232 文档版本:20200417

Page 245: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

iotx_mqtt_qos_t qos, iotx_mqtt_event_handle_func_fpt topic_handle_func, void *pcontext, int timeout_ms);

• 优化接口 IOT_MQTT_Subscribe(), 可以在MQTT连接尚未建立的时候就提前做离线的订阅, C-

SDK会在建连成功后立即发送订阅报文

OTA函数接口

• 由于MQTT函数接口的第1个参数handle可以传NULL, 也影响到基础版OTA函数接口 IOT_OTA_Init

的第3个参数可以接受NULL传参, 表示使用默认连接

void *IOT_OTA_Init(const char *product_key, const char *device_name, void *ch_signal);

Linkkit函数接口

新增以下接口用于完成物模型管理功能

函数名 说明

IOT_Linkkit_Open 创建本地资源, 在进行网络报文交互之前, 必须先调用此接口, 得到一个会话的句柄

IOT_Linkkit_Connect 对主设备/网关来说, 将会建立设备与云端的通信. 对于子设备来说, 将向云端注册该子设备(若需要), 并添加主子设备拓扑关系

IOT_Linkkit_Yield 若SDK占有独立线程, 该函数内容为空, 否则表示将CPU交给SDK让其接收网络报文并将消息分发到用户的回调函数中

IOT_Linkkit_Close 若入参中的会话句柄为主设备/网关, 则关闭网络连接并释放SDK为该会话所占用的所有资源

IOT_Linkkit_TriggerEvent 向云端发送__事件报文__, 如错误码, 异常告警等

IOT_Linkkit_Report 向云端发送__没有云端业务数据下发的上行报文__, 包括属性值/设备标签/二进制透传数据/子设备管理等各种报文

IOT_Linkkit_Query 向云端发送__存在云端业务数据下发的查询报文__, 包括OTA状态查询/OTA固件下载/子设备拓扑查询/NTP时间查询等各种报文

IOT_RegisterCallback 对SDK注册事件回调函数, 如云端连接成功/失败,有属性设置/服务请求到达, 子设备管理报文答复等

文档版本:20200417 233

Page 246: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

函数名 说明

IOT_Ioctl 对SDK进行各种参数运行时设置和获取, 以及运行状态的信息获取等, 实参可以是任何数据类型

去掉的接口

旧版的 linkkit_xxx() 和 linkkit_gateway_xxx() 接口作为编译时可选使能, 缺省不编译

注1:旧版的linkkit接口仍然可以通过在make.settings文件中的如下语句使能, 此时新版接口消失,

旧版接口重新出现

FEATURE_DEPRECATED_LINKKIT=y

注2: 为了减少设备端内存消耗,当用户调用SDK的API上传属性变化通知、事件通知到云端时SDK不

再检查数据格式的正确性,因此用户不再需要从云端导出TSL的json文件转换为C的字符串后放到C代

码中

HAL函数接口

• 删除了和已有接口 HAL_Reboot 重复的 HAL_Sys_reboot

1.2.1.4 常见问题列表注:本文的常见问题与Link Kit SDK的C语言版本相关,通用性的常见问题请参见:通用问题列表。

make menuconfig提示126错误码

用户使用make menuconfig对SDK进行裁剪时,提示126的错误:

234 文档版本:20200417

Page 247: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误原因:Ubuntu的版本过低,导致调用make menuconfig出错

解决办法:将Ubuntu进行升级到16.04及以上

如何编译SDK能够减小二进制尺寸

请注意以下的编译选项在 CFLAGS 中能够起到的作用

选项 说明

-Os 尺寸优化选项, GNU系列的工具链一般都会支持

-g3 调试附加选项, 如果不需要使用gdb调试, 可以去掉来减小尺寸

--coverage 覆盖率统计选项, 如果不需要用lcov统计代码覆盖率, 可以去掉来减小尺寸

-ffunction-sections 将函数分段摆放, 不被使用的函数将不进入最终的二进制, 加上此选项可减小最终的可执行程序/镜像大小

-fdata-sections 将数据分段摆放, 不被使用的变量将不进入最终的二进制, 加上此选项可减小最终的可执行程序/镜像大小

-Wl,--gc-sections 链接的时候让未使用的符号不进入最终的二进制,减小尺寸, 本选项需要和上面的2个选项组合使用

文档版本:20200417 235

Page 248: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

同时如下的功能开关可以考虑关闭, 以减小尺寸

开关 说明

FEATURE_AWSS_SUPPORT_ROUTER 配网中的路由器配网模式, 一般可以直接关闭, 以减小尺寸

FEATURE_AWSS_SUPPORT_PHONEASAP 配网中的手机热点配网模式, 一般不使用这种模式的时候也可以关闭, 以减小尺寸

如何解决嵌入式平台上 strtod() 不工作问题

在有些嵌入式平台上, 由于C库被定制, 标准的C99库函数 strtod() 可能不工作甚至引起崩溃和死机, 可

通过

setlocale(LC_ALL, "C");

的方式使能C库能力全集来解决

SDK几个库文件的编译时的链接顺序

当编译应用程序时链接SDK的顺序,请务必保持使用

-liot_sdk -liot_hal -liot_tls

这样的顺序来链接SDK提供的几个分库, 因为写在后面的都是对前面库的支撑

对于移植到Linux上使用的情况, 还需要以

-liot_sdk -liot_hal -liot_tls -lpthread -lrt

的方式来书写, 这是因为SDK在Linux下的HAL参考实现使用了pthread库和librt实时库

比如, 使用 dlopen() 接口打开我们的 libiot_sdk.so 这样的情况, 那么在编译SDK和使用它的应用程

序的时候, 就需要写成比如

$(TARGET): $(OBJS) $(CC) -o $@ $^ -liot_sdk -liot_hal -liot_tls -lpthread -lrt

的这个样子

不论是链接静态库, 还是链接动态库, 还是使用 dlopen() 等运行时动态加载的方式使用SDK, 应用程

序链接的时候都请确保按照上述顺序编写链接指令

236 文档版本:20200417

Page 249: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

获取动态链接库形态的SDK编译产物

由于C-SDK大部分情况下运行在非Linux的嵌入式操作系统上, 比如AliOS Things, 或者FreeRTOS等。

而这些操作系统并无Linux的动态链接库概念, 所以默认情况下SDK都是以静态库(libiot_sdk.a +

libiot_hal.a + libiot_tls.a)的方式输出。

可以用如下的修改方法调整默认的输出形态, 将SDK的编译产物从静态库的方式改成动态库。

获取libiot_sdk.so代替libiot_sdk.a。

以默认的 config.ubuntu.x86 配置文件为例, 如下的修改可以告诉构建系统要产生动态库形态的构建

产物。

--- a/src/board/config.ubuntu.x86+++ b/src/board/config.ubuntu.x86@@ -1,6 +1,5 @@ CONFIG_ENV_CFLAGS += \ -Os -Wall \- -g3 --coverage \ -D_PLATFORM_IS_LINUX_ \ -D__UBUNTU_SDK_DEMO__ \

@@ -19,6 +18,7 @@ CONFIG_ENV_CFLAGS += \ -DCONFIG_MQTT_RX_MAXLEN=5000 \ -DCONFIG_MBEDTLS_DEBUG_LEVEL=0 \

+CONFIG_LIB_EXPORT := dynamic

ifneq (Darwin,$(strip $(shell uname))) CONFIG_ENV_CFLAGS += -rdynamic

• 改动点1: 确保CFLAGS中没有-g3 --coverage这样的编译选项。

• 改动点2: 新增一行 CONFIG_LIB_EXPORT := dynamic。

• 改动点3: 重新运行 make reconfig 选择刚才修改到的 config.ubuntu.x86 配置文件, 或者被定制

的config文件,然后以make all 而不是 make 的方式来编译。

按照如上改法, make all之后在 output/release/lib/libiot_sdk.so 就可以获取动态库形态的SDK了,

其内容和默认的 libiot_sdk.a 是一致的。

$ ls output/release/lib/*.sooutput/release/lib/libiot_sdk.so

获取libiot_hal.so代替libiot_hal.a。

修改 src/ref-impl/hal/iot.mk, 新增如下这行。

LIBSO_TARGET := libiot_hal.so

文档版本:20200417 237

Page 250: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

然后运行:

make reconfigmake all

之后便可以在 output/release/lib/libiot_hal.so得到动态库形式的HAL参考实现的分库,其内容和

默认的 libiot_hal.a 是一致的。

获取libiot_tls.so代替libiot_tls.a。

修改 src/ref-impl/tls/iot.mk, 新增如下这行。

LIBSO_TARGET := libiot_tls.so

然后运行:

make reconfigmake all

之后便可以在output/release/lib/libiot_tls.so 得到动态库形式的TLS参考实现的分库,其内容和默

认的 libiot_tls.a 是一致的。

TLS/SSL连接错误

-0x7880/-30848/MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY

解释

云端把SSL连接断开了: The peer notified us that the connection is going to be closed

可能的原因和解决建议

• 设备端数据连接过于频繁, 触发云端限流, 断开设备

- 建议关闭设备, 等待一段时间(5分钟以后)再发起连接重试, 观察错误仍会出现

• 有多个设备使用相同的productKey和deviceName与云端建立连接, 导致被云端踢下线

- 建议检查当前使用的三元组是否可能被他人使用

• 设备端保活出错, 没有及时发送 MQTT ping packet, 或者被发送了没有及时到达云端

- 建议用抓包等方式确认心跳包有成功发出或者观察有没有收到来自服务端的 MQTT ping

response

• 如果一次都不能连接成功, 可以考虑是不是大小端字节序不匹配

- 目前C-SDK 默认是适配小端设备, 如果需在大端硬件上工作, 请添加全局编译选项 REVERSED

238 文档版本:20200417

Page 251: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

-0x7800/-30720/MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED

解释

认证错误: Verification of our peer failed

可能的原因和解决建议

• 证书错误

- 如果使用官方C-SDK对接, 证书固化在SDK内部, 不会出现. 若自行对接, 则需检查使用的证书是

否和阿里云官方证书匹配

• 日常环境SSL域名校验错误

- 如果出错时, 连接的是日常环境, 则考虑日常不支持SSL域名校验, 请将 FORCE_SSL_VERIFY 的

编译选项定义去掉

-0x7200/-29184/MBEDTLS_ERR_SSL_INVALID_RECORD

解释

收到非法数据: An invalid SSL record was received

可能的原因和解决建议

• TCP/IP协议栈收到的数据包出错, 需要排查协议栈方面问题

• SSL所运行的线程栈被设置的过小, 需调整线程栈大小

• SSL被配置的最大报文长度太小, 当网络报文长度超过该数值时, 则可能出现0x7200错误

- 可调整 MBEDTLS_SSL_MAX_CONTENT_LEN 的值, 重新编译再试

- MBEDTLS_SSL_MAX_CONTENT_LEN 的值, 目前已知最小不能小于 4096

-0x2700/-9984/MBEDTLS_ERR_X509_CERT_VERIFY_FAILED

解释

证书错误: Certificate verification failed, e.g. CRL, CA or signature check failed

可能的原因和解决建议

• 证书不匹配

- 若未使用官方C-SDK对接, 请检查证书是否和阿里云官网提供下载的一致

• 时钟不对

- 确认系统时间是否准确, 系统时间不对(比如默认的1970-01-01), 也会导致证书校验失败

文档版本:20200417 239

Page 252: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

-0x0052/-82/MBEDTLS_ERR_NET_UNKNOWN_HOST

解释

DNS域名解析错误: Failed to get an IP address for the given hostname

可能的原因和解决建议

• 大概率是设备端当前网络故障, 无法访问公网

- 如果是WiFi设备, 检查其和路由器/热点之间的连接状况, 以及上联路由器是否可以正常访问公

• 需要通过类似 res_init() 之类的调用强制C库刷新DNS解析文件

- 在Linux系统上, 域名解析的系统调用 getaddrinfo() 的工作是依赖域名解析文件 /etc/resolv.

conf

- 对某些嵌入式Linux, 可能会有 libc 库读取过时的 /etc/resolv.conf 问题

- 对于这类系统, 域名解析请求不论是早于还是晚于域名解析文件的更新, 都会读到过时的信息,

进而造成域名解析失败

这种现象产生的原因是DNS文件的更新晚于MQTT的域名解析请

求, 这样 getaddrinfo() 系统调用就会得到一个 EAI_AGAIN 错误

然而, 如果不通过 res_init(), C库中的 getaddrinfo() 即使被重试

逻辑调用也仍然读取过时的DNS文件, 并继续得到 EAI_AGAIN 错

例如, 可以改动 HAL_TLS_mbedtls.c

#include <arpa/nameser.h>#include <resolv.h>

...

...

if ((ret = getaddrinfo(host, port, &hints, &addr_list)) != 0) { if (ret == EAI_AGAIN) res_init();

return (MBEDTLS_ERR_NET_UNKNOWN_HOST);}

以上只是一个示意的改法, res_init()本身也是一个过时的函数, 所以不建议进入SDK的官方代码, 用户

可以酌情加在合适的位置

240 文档版本:20200417

Page 253: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

-0x0044/-68/MBEDTLS_ERR_NET_CONNECT_FAILED

解释

socket连接失败: The connection to the given server / port failed

可能的原因和解决建议

• TCP连接失败

- 请确认连接的目标IP地址/域名, 以及端口号是否正确

-0x0043/-67/MBEDTLS_ERR_NET_BUFFER_TOO_SMALL

解释

SSL报文缓冲区过短: Buffer is too small to hold the data

可能的原因和解决建议

• SSL被配置的最大报文长度太小

- 可调整 MBEDTLS_SSL_MAX_CONTENT_LEN 的值, 重新编译再试

- MBEDTLS_SSL_MAX_CONTENT_LEN 的值, 目前已知最小不能小于 4096

-0x0042/-66/MBEDTLS_ERR_NET_SOCKET_FAILED

解释

创建socket失败: Failed to open a socket

可能的原因和解决建议

• 系统可用的socket可能已全部被申请, 在有些平台上, 能被开启的socket数量, 有上限的

- 检查当前的流程是否有socket的泄漏, 有些socket使用完后没有close

- 如果流程正常, 确需同时建立多个socket, 请调整socket的个数上限

MQTT连接

-35/MQTT_CONNACK_BAD_USERDATA_ERROR

解释

发起MQTT协议中的Connect操作失败: Connect request failed with the server returning a bad

userdata error

可能的原因和解决建议

文档版本:20200417 241

Page 254: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 使用了错误的设备三元组

- 建议检查 productKey/deviceName/deviceSecret 是否正确并且是同一套

• 三元组传入的参数不正确

- 建议检查C函数的传参过程

• 设备三元组被禁用

- 若经检查确系禁用, 请在控制台或是使用服务端相应API解除禁用

-37/MQTT_CONNACK_IDENTIFIER_REJECTED_ERROR

解释

云端认为设备权限不足而拒绝设备端的连接请求: CONNACK 报文中的错误码是 2

可能的原因和解决建议

• MQTT的Connect报文参数中, clientId的上报内容和协议预期不符, 这通常发生在不使用官方SDK

而使用第三方MQTT自行对接时

• 建议检查在控制台创建当前设备三元组的账号, 是否有权限, 如是否有发生欠费等

-42/MQTT_PUSH_TO_LIST_ERROR

解释

订阅或是发布(QoS1)太多太快, 导致SDK内部队列满了而出错

可能的原因和解决建议

• 如果是订阅过程中发生的错误, 说明当前订阅使用的队列长度不够

- 可以考虑调整 IOTX_MC_SUB_NUM_MAX 的值

• 如果是发布过程中发生的错误, 可能是发送的频率太快, 或是网络状态不佳

- 可以考虑使用QoS0来发布

- 可以考虑调整 IOTX_MC_REPUB_NUM_MAX 的值

什么是域名直连, 如何开启

C-SDK 的 2.0 以上版本, MQTT连接有两种方式, 一种是认证模式, 一种是域名直连模式

• 认证模式是设备先用 HTTPS 方式访问类似 https://iot-auth.cn-shanghai.aliyuncs.com:443

的地址, 进行鉴权

• 鉴权通过之后, 再用 MQTT 方式连接到类似 public.iot-as-mqtt.cn-shanghai.aliyuncs.com:

1883 的 MQTT 服务器地址

242 文档版本:20200417

Page 255: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 域名直连模式是设备直接用 MQTT 方式连接到类似 ${productKey}.iot-as-mqtt.cn-shanghai.

aliyuncs.com:1883的 MQTT 服务器地址

• 这样不需要访问 HTTPS+MQTT 两台服务器才建立连接, 更快建立连接, 耗费的端上资源也更少

2.0 以上的版本, 默认已经开启了直连模式, 如果配置文件 make.settings 不是默认的状态了, 那么

打开 make.setting 文件, 在文件尾部写入 FEATURE_MQTT_DIRECT = y, 然后运行 make 命令重新编

译, 即可确保开启直连模式

MQTT协议版本是多少

C-SDK 的 2.0 以上版本, 封装的MQTT协议版本号是 3.1.1

例程 mqtt-example 连接上线后会很快下线, 如何修改可以一直处于在线状态

mqtt-example 例程本身的逻辑是发送一次消息后会自动退出

若需要此例程保持长期在线, 执行命令时加上 "loop" 参数即可, 例如:

.output/release/bin/mqtt-example loop

当您这样做时, 请确保使用自己申请的 productKey/deviceName/deviceSecret 覆盖代码中的设

备身份信息后后重新编译例程

因为官方SDK的代码中默认编写的是一台公用设备的信息, 有其他人同时使用时, 您会被踢下线, 同一

组设备信息只能同时在线一个连接

如何持续的接收MQTT消息

需要循环多次的调用 IOT_MQTT_Yield 函数, 在其内部会自动的维持心跳和接收云端下发的MQTT消

可以参考 examples 目录下, mqtt-example.c 里面的 while 循环部分

心跳和重连

心跳的时间间隔如何设置

在 IOT_MQTT_Construct 的入参中可以设置 keepalive_interval_ms 的值, C-SDK用这个值作为心跳

间隔时间

keepalive_interval_ms 的取值范围是 60000 - 300000, 即最短心跳间隔为1分钟, 最长心跳间隔为5

分钟

文档版本:20200417 243

Page 256: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

设备端是如何侦测到需要重连(reconnect)的

设备端C-SDK会在 keepalive_interval_ms 时间间隔过去之后, 再次发送 MQTT ping request, 并等

待 MQTT ping response

如果在接下来的下一个 keepalive_interval_ms 时间间隔内, 没有收到对应的 ping response

或是在进行报文的上行发送(send)或者下行接收(recv)时发生异常, 则 C-SDK 就认为此时网络断开了,

需要进行重连

设备端的重连机制是什么

C-SDK 的重连动作是内部触发, 无需用户显式干预. 对于使用基础版的用户, 需要时常调用

IOT_MQTT_Yield 函数将 CPU 交给SDK, 重连就在其中发生

重连如果不成功, 会在间隔一段时间之后持续重试, 直到再次连接成功为止

相邻的两次重连之间的间隔时间是指数退避+随机数的关系, 比如间隔1s+随机秒数, 间隔2s+随机秒

数, 间隔4s+随机秒数, 间隔8s+随机秒数... 直到间隔达到了间隔上限(默认60s)

关于 IOT_MQTT_Yield

IOT_MQTT_Yield 的作用

IOT_MQTT_Yield 的作用主要是给SDK机会去尝试从网络上接收数据

因此在需要接收数据时(subscribe/unsubscribe之后, publish之后, 以及希望收到云端下推数据时),

都需要主动调用该函数

IOT_MQTT_Yield 参数 timeout 的意义

IOT_MQTT_Yield 会阻塞住 timeout 指定的的时间(单位毫秒)去尝试接收数据, 直到超出这个时间, 才

会返回调用它的函数

IOT_MQTT_Yield 与 HAL_SleepMs 的区别

都会阻塞一段时间才返回, 但是 IOT_MQTT_Yield 实质是去从网络上接收数据

而 HAL_SleepMs 则是什么也不做, 单纯等待入参指定的时间间隔过去后返回

订阅相关

如果订阅了多个topic, 调用一次IOT_MQTT_Yield, 可能接收到多个topic的消息吗

调用一次 IOT_MQTT_Yield, 如果多个topic都被订阅成功并且都有数据下发, 则可以一次性接收到来

自多个topic的消息

244 文档版本:20200417

Page 257: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

什么情况下会发生订阅超时

• 调用 IOT_MQTT_Construct 和云端建立MQTT连接时, 其入参中可以设置请求超时时间 request_ti

meout_ms 的值

• 如果两倍 request_timeout_ms 时间过去, 仍未收到来自云端的 SUBACK 消息, 则会触发订

阅(Subscribe)超时

• 超时的事件会通过 IOT_MQTT_Construct 入参中设置的 event_handle 回调函数通知到用户

• 在调用 IOT_MQTT_Subscribe 之后, 需要尽快执行 IOT_MQTT_Construct 以接收SUBACK, 请勿使

用 HAL_SleepMs

发布相关

发布(Publish)的消息最长是多少, 超过会怎么样

• C-SDK的代码上来说, MQTT的消息报文长度, 受限于 IOT_MQTT_Construct 入参中 write_buf 和

read_buf 的大小

• 从云端协议上来说, MQTT消息报文长度不能超过256KB, 具体查阅 官网限制说明页面 为准

• 如果实际上报消息长度大于C-SDK的限制, 消息会被丢掉

被发布消息payload格式是怎么样的

阿里云物联网平台并没有指定pub消息的payload格式

需要客户根据应用场景制定自己的协议, 然后以JSON格式或其它格式, 放到pub消息载体里面传给服

务端

云端/协议问题

物联网平台云端是否一有消息就立刻推送给订阅的设备而不做保存

消息一到达云端, 就会分发给不同的设备订阅者, 云端服务器不进行保存, 目前不支持 MQTT 协议中的

will 和 retain 特性

MQTT长连接时, 云端如何侦测到设备离线的

云端会根据用户调用 IOT_MQTT_Construct 时传入的 keepalive_interval_ms, 作为心跳间隔, 等待

MQTT ping request

如果在约定的心跳间隔过去之后, 最多再等5秒钟, 若还是没有收到 MQTT ping request, 则认为设备

离线

文档版本:20200417 245

Page 258: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

CoAP上云问题

认证超时失败, 目前总结下来分为下述两种情况

连接失败的时候, ssl->state为MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC的情况

在出现问题的一次测试中通过tcpdump进行抓包, 结果通过wireshark展示如下图. 其中client(ip地

址为30.5.88.208)发出了握手数据包(包括client key exchange, change cipher spec, encrypted

handshake message),但是服务端并没有回复change cipher spec的数据包, 从而导致coap连云

卡在这一步. 卡在这一步后, 但如果等待2s后没有等到数据, 客户端会再进行两次尝试超时等待(4s, 8s

);如果3次都等不到服务端发来的change cipher spec的数据包, 则退出handshake过程, 导致连接失

败由上分析可知, 这个问题的根因是在服务端.

连接失败的时候, ssl->state为MBEDTLS_SSL_HANDSHAKE_OVER的情况

在出现问题的一次测试中通过tcpdump进行抓包, 结果通过wireshark展示如下图. 服务

端(106.15.213.197)发来的certificate数据包的顺序出现了错乱, server_hello_done这

个certificate数据包并不是作为最后一个certicate包, 而是作为倒数第二个(对比上图即能发现). 在这

种情况下, 客户端解析服务端的certificate信息失败, 重新发送client hello消息等待server端回复. 客

户端尝试过进行三次尝试超时等待(2s, 4s, 8s)后还没收到数据包, 就主动放弃, 导致连接失败. 由上分

析可知, 这个问题的根因是在服务端未能正确返回握手信息

CoAP上云连接的云端URI是什么

• 在调用 IOT_CoAP_Init 的时候, 可以设置其参数 iotx_coap_config_t 里面的 p_url

246 文档版本:20200417

Page 259: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 如果 p_url 值为NULL, 则C-SDK会自动使用 IOTX_ONLINE_DTLS_SERVER_URL 这个宏所定义的

默认URL

#define IOTX_ONLINE_DTLS_SERVER_URL "coaps://%s.iot-as-coap.cn-shanghai.aliyuncs.com:5684"

• 其中 %s 是使用 p_devinfo 里面的 product_key, 所以请确保在初始化 iotx_coap_config_t 的时

候一定要对 p_devinfo 赋值

IOT_CoAP_SendMessage 发送的消息必须是JSON格式吗, 如果不是JSON会出现什么错误

• 目前, 除了支持JSON格式外, 也可以支持CBOR格式

• 因为是与云端通信, 需要使用指定格式, 否则可能会出现无法解析的问题

关于 IOT_CoAP_Yield

如何设置 IOT_CoAP_Yield 处理结果最大等待时间?

目前默认设置是2000ms, 可以修改 COAP_WAIT_TIME_MS 这个宏进行调整

HTTP上云问题

认证连接

HTTPS进行设备认证时, Server会返回的错误码及其含义

• 10000: common error(未知错误)

- HTTPS报文是有一定格式要求, 必须符合要求server才能支持

- ContentType只支持"application/json"

- 只支持HTTPS

- 只支持POST方法

• 40000: request too many(请求次数过多, 流控限制)

- 同一个设备在一天内的认证次数是有限制的

- 解决方法: 每次认证获得的token是有48小时有效期的, 过期前可以反复使用, 无需每次都去认

证获取新的token

• 400: authorized failure(认证失败)

- 服务器认为鉴权参数是不合法的, 鉴权失败

- 解决方法: 检查IOTX_PRODUCT_KEY, IOTX_DEVICE_NAME, IOTX_DEVICE_SECRET,

IOTX_DEVICE_ID是不是从控制台获得的正确参数

文档版本:20200417 247

Page 260: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

TLS连接问题

设备端TLS密码算法

目前C-SDK连接云端用到的默认TLS算法是: TLS-RSA-WITH-AES-256-CBC-SHA256

云端TLS密码算法

目前阿里云IoT平台支持的TLS算法清单如下:

• TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384

• TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384

• TLS_RSA_WITH_AES_256_CBC_SHA256

• TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384

• TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384

• TLS_DHE_RSA_WITH_AES_256_CBC_SHA256

• TLS_DHE_DSS_WITH_AES_256_CBC_SHA256

• TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA

• TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA

• TLS_RSA_WITH_AES_256_CBC_SHA

• TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA

• TLS_ECDH_RSA_WITH_AES_256_CBC_SHA

• TLS_DHE_RSA_WITH_AES_256_CBC_SHA

• TLS_DHE_DSS_WITH_AES_256_CBC_SHA

• TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256

• TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256

• TLS_RSA_WITH_AES_128_CBC_SHA256

• TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256

• TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256

• TLS_DHE_RSA_WITH_AES_128_CBC_SHA256

• TLS_DHE_DSS_WITH_AES_128_CBC_SHA256

• TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA

• TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA

• TLS_RSA_WITH_AES_128_CBC_SHA

• TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA

• TLS_ECDH_RSA_WITH_AES_128_CBC_SHA

248 文档版本:20200417

Page 261: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• TLS_DHE_RSA_WITH_AES_128_CBC_SHA

• TLS_DHE_DSS_WITH_AES_128_CBC_SHA

• TLS_ECDHE_ECDSA_WITH_RC4_128_SHA

• TLS_ECDHE_RSA_WITH_RC4_128_SHA

• SSL_RSA_WITH_RC4_128_SHA

• TLS_ECDH_ECDSA_WITH_RC4_128_SHA

• TLS_ECDH_RSA_WITH_RC4_128_SHA

• TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

• TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

• TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

• TLS_RSA_WITH_AES_256_GCM_SHA384

• TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384

• TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384

• TLS_DHE_RSA_WITH_AES_256_GCM_SHA384

• TLS_DHE_DSS_WITH_AES_256_GCM_SHA384

• TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

• TLS_RSA_WITH_AES_128_GCM_SHA256

• TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256

• TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256

• TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

• TLS_DHE_DSS_WITH_AES_128_GCM_SHA256

• TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA

• TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA

• SSL_RSA_WITH_3DES_EDE_CBC_SHA

• TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA

• TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA

• SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA

• SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA

• SSL_RSA_WITH_RC4_128_MD5

• TLS_EMPTY_RENEGOTIATION_INFO_SCSV

1.2.1.5 移植指南

文档版本:20200417 249

Page 262: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.1 移植概述C语言Link Kit SDK的结构如下图所示:

SDK被设计为可以在各种OS/硬件平台上运行,因此凡是与OS、目标硬件相关的操作都被抽象为HAL

函数,设备商在开发产品时除了需要调用SDK的API实现产品业务逻辑外,还需要对SDK依赖的HAL

函数进行实现。

设备商下载SDK之后,进行的操作步骤如下:

1. SDK功能配置

2. 进行HAL函数的实现

3. 调用SDK提供的API进行产品功能实现

4. 对SDK进行编译

SDK功能配置/裁剪

用户下载SDK之后,首先需要决定自己需要使用到哪些功能,通过SDK提供的配置工具对SDK进行配

置/裁剪。SDK为windows环境提供的代码配置工具是SDK根目录下的config.bat,在Linux环境下在

SDK的根目录使用make menuconfig对SDK进行配置,配置页面如下所示:

250 文档版本:20200417

Page 263: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

可以参考基于Make的编译系统说明了解各个配置选项。

SDK默认使用同步通信机制与设备上的TCP/IP协议栈交互,如果目标硬件平台的TCP/IP协议栈是异

步方式的(比如Nucleus),那么需要将SDK配置为使用异步协议栈,请参考“SDK的同步与异步通

信”模式了解更多细节。

HAL函数实现

根据用户选择的功能不同,用户需要实现的HAL函数也有区别,在相应功能的开发文档中将会有相关

需要实现的HAL函数的描述。

调用SDK提供的API进行产品功能实现

可以参考“编程指南”下面的各个功能的开发说明文档了解编程细节,在SDK中也提供了一些代码示

例,用户可以基于这些example进行产品功能实现。

SDK编译

将SDK移植到目标嵌入式平台有两种方式:

• 使用SDK自带的编译系统,当开发环境为Linux时使用

• 抽取SDK的代码文件加入到用户的开发环境编译

使用SDK自带的编译系统

如果使用Linux作为开发环境,可以直接使用SDK自带的编译系统对SDK进行编译,

使用SDK自带的编译系统时, 您需要

• 准备一台 Linux 的开发主机, 安装 Ubuntu16.04 64bits或以上版本

• 运行 make menuconfig 命令配置功能点

文档版本:20200417 251

Page 264: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 在 tools/board 目录下新增自己的硬件平台描述文件,进行交叉编译配置

• 运行 make reconfig 选择自己的平台

• 运行 make, 产物是已经交叉编译好的 libiot_sdk.a, 在 output/release/lib 目录下

用户可以通过文档:基于Make的编译系统说明 了解编译系统如何使用

可参考文档基于Make的交叉编译示例了解交叉编译的过程

抽取代码加入用户的开发环境

KEIL、IAR这样的开发工具无法使用make,需要将SDK中的功能代码抽取出来加入工程进行编译。

代码抽取以及编译过程如下:

• 准备一台 Linux 的开发主机, 安装 Ubuntu16.04 64bits;或者准备一台 Windows 的开发主机

• 运行 make menuconfig 命令(Ubuntu) 或者 config.bat 脚本(Windows)配置需要使用到

的SDK功能点

• 运行 extract.sh 脚本(Ubuntu) 或者 extract.bat 脚本(Windows)根据被选择的功能点抽取代码

• 用户选中的SDK功能相关的代码将被放置在 output/eng 目录下

• 用户将output/eng下的代码添加到开发工具的项目中进行编译

用户可参考文档基于代码抽取时的移植过程了解相关过程。

1.2.1.5.2 SDK的同步与异步通信模式C-SDK需要被移植到的大多数嵌入式平台都使用 同步 的底层通信模型, 能够支持C-SDK用 轮询 的方

式主动去网络上收取报文

• 比如, 我们熟悉的嵌入式 Linux 系统, Windows 系统, 以及大部分配备lwip协议栈通信的RTOS比

如 FreeRTOS 系统等, 它们都支持上层应用随时去 主动 收取网络报文

• 在这样的系统上, C-SDK这样的网络应用软件, 可以 随时的主动的** 调用类似 read() 这样的函数

接口从已开启的socket接口收取报文

因此, C-SDK的默认方式通过 轮询方式 去和底层通信软件模块交互: 当它的 IOT_MQTT_Yield() 接口

被调用时, 去做从网络上收取云端下发报文的动作。SDK初始化以及收发数据的示意图如下所示:

252 文档版本:20200417

Page 265: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

下面对SDK的同步通信模式进行简单的描述:

• 首先应用程序通过 IOT_MQTT_Construct() 建立IoT设备与云端之间的长连接通道

• 然后在这个长连接上用 IOT_MQTT_Subscribe() 订阅一些Topic, 表达自己将可接受哪些消息报文

的下发, 并设置这些消息到达后处理它们的回调函数

• 达到初始化就绪状态, 进入主要的业务逻辑循环

- 在该循环中, 调用 IOT_MQTT_Yield(), 不仅可以收取云端下发的报文, 也完成了必要的数据重发

和MQTT Keepalive报文发送

- 应用程序检查是否有属性发生变化需要通知物联网平台, 调用 IOT_MQTT_Publish(), 将消息报

文向云端上报

异步通信模式

有的TCP/IP协议栈不提供同步方式的数据接收接口,比如Nucleus操作系统;或者有的客户认为同

步方式效率不高,希望设备收到数据时可以主动将数据发送给SDK,那么可以使用SDK的异步通信模

式。

异步通信模式与同步通信模式的最大区别在于:数据报文的接收发起方不再是应用程序/SDK,而是

设备的协议栈或者底层通信模块。

文档版本:20200417 253

Page 266: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在V3.0.1及以上版本, C-SDK支持将SDK切换到异步通信模式, 在SDK提供的配置工具中可以通过Main

Menu -> MQTT Configurations -> FEATURE_ASYNC_PROTOCOL_STACK 使能异步开关。使用异步

方式通信的SDK的收发数据示意图如下所示:

下面对上面的数据收发过程进行简单的描述:

• 首先应用通过 IOT_MQTT_Construct() 建立IoT设备与云端之间的长连接通道

• 当设备从SDK创建的socket上收到网络报文时调用SDK提供的接口 IOT_MQTT_Nwk_Event_H

andler(),由该函数将数据发送给SDK进行处理

• IOT_MQTT_Yield() 将 只发不收

- 重传云端尚未应答的 QoS1 消息仍然进行

- 若达到心跳间隔, 则发送心跳维持连接仍然进行

- 不会调用 HAL_TCP_Read() 等接口去网络收取报文

SDK在 MTK2503/MTK6261 的 Nucleus 上使用异步通信模式进行了集成, 详见: MTK2503/

MTK6261+Nucleus移植示例

254 文档版本:20200417

Page 267: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.3 基于Make的编译说明在"快速体验"中使用到了make进行sdk的编译, 本章对make系统进行更详细的描述, 以及讲解如何

对SDK进行裁剪

命令 解释

make distclean 清除一切构建过程产生的中间文件, 使当前目录仿佛和刚刚clone下来一样

make 使用默认的或已选中的平台配置文件平台配置文件开始编译

make env 显示当前编译配置, 非常有用, 比如可显示交叉编译链, 编译CFLAGS等

make reconfig 弹出多平台选择菜单, 用户可按数字键选择, 然后根据相应的硬件平台配置开始编译

make config 显示当前被选择的平台配置文件

make menuconfig 以图形化的方式编辑和生成功能配置文件make.settings

make help 打印帮助文本

SDK裁剪

对V3.0.1以上版本, 可以用 make menuconfig 命令或者 config.

bat 脚本, 分别在Linux/Windows主机上图形化的配置SDK

下面是运行图形化配置工具之后的图示:

文档版本:20200417 255

Page 268: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在上面的界面中

• 按下空格键可以选中或者失效某个功能, 使用小键盘的上下键来在不同功能之间选择

• 如果想知道每个选项的具体含义, 先用方向键将高亮光条移到那个选项上, 再按键盘上的 "h"按键,

将出现帮助文本, 对选项进行详细说明。

注意: 不建议手动编辑 make.settings 文件改动配置, 一切配置都需通过上面的图形界面进行

配置选项说明:

FEATURE_MQTT_COMM_ENABLED

• MQTT上云功能开关, 所谓MQTT上云是指搭载了C-SDK的嵌入式设备和阿里云服务器之间使用

MQTT 协议进行连接和交互。本选项使能之后,SDK将提供MQTT相关的API。

FEATURE_COAP_COMM_ENABLED

• CoAP上云功能开关, 所谓CoAP上云是指搭载了C-SDK的嵌入式设备和阿里云服务器之间使用

CoAP 协议进行连接和交互

FEATURE_HTTP_COMM_ENABLED

• HTTP/S上云功能开关, 所谓HTTP/S上云是指搭载了C-SDK的嵌入式设备和阿里云服务器之间使用

HTTP 协议或 HTTPS 协议进行连接和交互

FEATURE_DYNAMIC_REGISTER

• 一型一密/动态注册功能开关, 所谓动态注册是指不需要为同个品类下的不同设备烧录不同的三元

组, 只需烧录相同的productSecret, 每个设备在网络通信中动态注册自己

FEATURE_DEPRECATED_LINKKIT

• 高级版接口风格的开关, 配置进行高级版物模型相关的编程时, C-SDK是提供 linkkit_xxx_yyy() 风

格的旧版接口, 还是提供 IOT_Linkkit_XXX() 风格的新版接口

FEATURE_DEV_BIND_ENABLED

V2.3.0之后的版本才新增的这个开关

• 绑定功能的开关, 只有用C-SDK连接飞燕平台的客户才需要关注并打开它, 用于使能设备被飞燕的

公版app控制, 可绑定设备和用户账号

FEATURE_DEVICE_MODEL_GATEWAY

在V2.3.0以前的版本中, 这个开关的曾用名是 FEATURE_EN

HANCED_GATEWAY

256 文档版本:20200417

Page 269: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 高级版网关能力的开关, 配置进行高级版物模型相关的编程时, C-SDK是提供 linkkit_xxx_yyy() 风

格的单品接口, 还是提供 linkkit_gateway_xxx_yyy() 风格的网关接口

FEATURE_HTTP2_COMM_ENABLED

• HTTP2上云功能开关, 所谓HTTP2上云是指搭载了C-SDK的嵌入式设备和阿里云服务器之间使用

HTTP2 协议进行连接和交互

FEATURE_MQTT_DIRECT

• MQTT直连功能开关, 所谓MQTT直连是指设备和阿里云服务器之间使用 MQTT 协议进行连接, 而不

会前置基于 HTTP 协议认证的交互过程

FEATURE_OTA_ENABLED

• 固件升级功能开关, 所谓固件升级是指设备从阿里云服务器上下载用户在IoT控制台中上传的固件

文件功能

FEATURE_DEVICE_MODEL_ENABLED

在V2.3.0以前的版本中, 这个开关的曾用名是 FEATURE_SD

K_ENHANCE

• 高级版物模型能力的功能开关, 所谓高级版物模型能力是指设备可使用基于服务/属性/事件三要素

的Alink协议和服务端通信

FEATURE_SUPPORT_TLS

• 在TLS层是否使用TLS的功能开关, 关闭则代表用不带TLS加密的TCP连接连云

FEATURE_WIFI_PROVISION_ENABLED

在V2.3.0以前的版本中, 这个开关的曾用名是 FEATURE_WI

FI_AWSS_ENABLED

• WiFi配网的功能开关, 所谓WiFi配网是阿里巴巴自研的一种从手机app发送WiFi网络的SSID和密码

给设备端的通信协议

输出说明

使用make进行成功编译, 将会打印类似如下的表格, 给出每个模块的ROM占用, 以及静态RAM占用的

统计

| RATE | MODULE NAME | ROM | RAM | BSS | DATA ||-------|----------------------|---------|---------|--------|--------|| 45.3% | src/dev_model | 28563 | 216 | 188 | 28 |

文档版本:20200417 257

Page 270: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

| 28.1% | src/mqtt | 17737 | 28 | 28 | 0 || 25.7% | src/infra | 16195 | 544 | 60 | 484 || 1.65% | src/dev_sign | 1045 | 48 | 0 | 48 ||-------|----------------------|---------|---------|--------|--------|| 100% | - IN TOTAL - | 63540 | 836 | 276 | 560 |

用户需要关注的输出产物都在output/release目录下。

output/release/lib

产物文件名 说明

libiot_hal.a HAL接口层的参考实现, 提供了 HAL_XXX() 接口

libiot_sdk.a SDK的主库, 提供了 IOT_XXX 接口和 linkkit_xxx() 接口

libiot_tls.a 裁剪过的 mbedtls, 提供了 mbedtls_xxx() 接口,支撑 libiot_hal.a

output/release/include

产物文件名 说明

mqtt_api.h 当用户在配置环节选中"MQTT上云"时出现, 列出MQTT上云功能点提供的用户API

dev_model_api.h 当用户在配置环节选中"物模型管理"时出现, 列出物模型管理功能点提供的用户API

选中了什么功能, 该功能的API就会以 <功能名字>_api.h 的形式出现, 依次类推

output/release/bin

如果是在主机环境下不做交叉编译(Ubuntu/Windows), 是可以产生主机版本的demo程序, 可以直接

运行的, 比如

产物文件名 说明

linkkit-example-solo 物模型管理功能的例程, 可演示 linkkit_xxx() 接口的使用

mqtt-example MQTT上云功能的例程, 可演示 IOT_XXX() 接口的使用

配置系统组成部分

用户输入

设备端C-SDK的构建配置系统, 有以下输入文件可接受用户的配置, 您可以通过编辑它们, 将配置输入

到构建系统中

258 文档版本:20200417

Page 271: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 功能配置文件: 即顶层目录的 make.settings 文本文件

• 平台配置文件: 即目录 tools/board 下的 config.xxx.yyy 系列文件, 也称config文件

构建系统最终是依据 config.xxx.yyy 文件进行编译, 然而由于功能配置/裁剪更为常用, 我们将它额外

抽取到了 make.settings 中

config.xxx.yyy 主要关注目标嵌入式硬件平台的工具链程序和编

译/链接选项的指定, 用于跨平台移植

config.xxx.yyy 此外也能以 CONFIG_ENV_CFLAGS += ... 的语法

新增自定义 CFLAGS, 同理 CONFIG_ENV_LDFLAGS += ... 可以指

定链接选项

make.settings 则是在已被确定的目标硬件平台上, 专注于C-SDK

的功能模块裁剪或者配置, 用于裁剪功能模块

构建单元

从工程顶层目录以下, 每一个含有iot.mk的子目录, 都被构建系统认为是一个__构建单元__

每一个构建单元, 若相对顶级makefile的路径是bar, foo/bar1, 则可以用make bar, make foo/bar1

这样的命令单独编译

tools/board/config.xxx.yyy

文件名形式为config.<VENDOR>.<MODEL>的文本文件, 会被构建系统认为是硬件平台配置文件, 每

个文件对应一个嵌入式软硬件平台

• 其中部分, 一般是指明嵌入式平台的软件OS提供方, 如mxchip, ubuntu, win7等. 另外, 这也会导

致构建系统到$(IMPORT_DIR)/<VENDOR>目录下寻找预编译库的二进制库文件和头文件

• 其中部分, 一般是标明嵌入式平台的具体硬件型号, 如mtk7687, qcom4004等, 不过也可以写上其

它信息, 因为构建系统不会去理解它, 比如mingw32, x86-64等

调试方式

• 在make ...命令行中, 设置TOP_Q变量为空, 可打印工程顶层的执行逻辑, 例如硬件平台的选择,

SDK主库的生成等

make .... TOP_Q=

• 在make ...命令行中, 设置Q变量为空, 可打印模块内部的构建过程, 例如目标文件的生成, 头文件

搜寻路径的组成等

make .... Q=

文档版本:20200417 259

Page 272: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 可以用make foo/bar单独对foo/bar进行构建, 不过, 这可能需要先执行make reconfig

• 可以进入.O/foo/bar路径, 看到完整的编译临时目录, 有makefile和全部源码, 所以在这里执行

make, 效果和make foo/bar等同

交叉编译相关

以下是常在 tools/board/config.xxx.yyy 平台配置文件中使用的变量

变量 说明

CONFIG_ENV_CFLAGS 指定全局的CFLAGS编译选项, 传给compiler, 例如CONFIG_ENV_CFLAGS += -DDEBUG

CONFIG_ENV_LDFLAGS 指定全局的LDFLAGS链接选项, 传给linker, 例如CONFIG_ENV_LDFLAGS += -lcrypto

CROSS_PREFIX 指定交叉编译工具链共有的前缀, 例如CROSS_PREFIX := arm-none-eabi-, 会导致构建系统使用arm-none-eabi-gcc和arm-none-eabi-ar, 以及arm-none-eabi-strip等

OVERRIDE_CC 当交叉工具链没有共有的前缀或者前缀不符合prefix+gcc/ar/strip类型时, 例如armcc, 可用OVERRIDE_CC = armcc单独指定C编译器

OVERRIDE_AR 当交叉工具链没有共有的前缀或者前缀不符合prefix+gcc/ar/strip类型时, 例如armar, 可用OVERRIDE_AR = armar单独指定库压缩器

OVERRIDE_STRIP 当交叉工具链没有共有的前缀或者前缀不符合prefix+gcc/ar/strip类型时, 例如armcc没有对应的strip程序, 可用OVERRIDE_STRIP = true单独指定strip程序不执行

CONFIG_LIB_EXPORT 指定SDK产生的二进制库的形式, 例如``CONFIG_LIB_EXPORT := dynamic可以指定产生linux上的libiot_sdk.so动态库文件, 默认为产生跨平台的libiot_sdk.a`静态库

目录文件相关

变量 说明

CONFIG_mmm/nnn 指定mmm/nnn目录是否需要编译的开关, 例如CONFIG_mmm/nnn :=的写法会导致该目录被跳过编译

260 文档版本:20200417

Page 273: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.4 基于Make的交叉编译示例提示: 如果您通过将SDK中的文件抽取出来的方式编译SDK, 则可以跳过本章

本文以将SDK移植到 arm-linux 平台为例, 演示一个完整的交叉编

译移植过程

对于嵌入式硬件平台的情况, 对编译出目标平台的libiot_sdk.a, 需要经历如下几个步骤:

• 在tools/board/目录下添加一个对应的配置文件, 文件名规范为config.XXX.YYY, 其中XXX部分就

对应后面wrappers/os/XXX目录的HAL层代码

• 在配置文件中, 至少要指定:

- 交叉编译器 OVERRIDE_CC 的路径

- 交叉链接器 OVERRIDE_LD 的路径

- 静态库压缩器 OVERRIDE_AR 的路径

- 编译选项 CONFIG_ENV_CFLAGS, 用于C文件的编译

- 链接选项 CONFIG_ENV_LDFLAGS, 用于可执行程序的链接

• 尝试编译SDK, 对可能出现的跨平台问题进行修正, 直到成功产生目标格式的libiot_sdk.a

• 最后, 您需要以任何您喜欢的编译方式, 产生目标架构的libiot_hal.a

• 若目标平台尚未被适配, 则libiot_hal.a对应的源代码在C-SDK中并未包含, 需要您自行实现HAL_

*()接口

下面以某款目前未官方适配的 arm-linux 目标平台为例, 演示如何编译出该平台上可用的libiot_sdk.

a

安装交叉编译工具链

仍以Ubuntu16.04开发环境为例

$ sudo apt-get install -y gcc-arm-linux-gnueabihf

$ arm-linux-gnueabihf-gcc --versionarm-linux-gnueabihf-gcc (Ubuntu/Linaro 4.8.4-2ubuntu1~14.04.1) 4.8.4Copyright (C) 2013 Free Software Foundation, Inc.This is free software; see the source for copying conditions. There is NOwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

添加配置文件

$ touch tools/board/config.arm-linux.demo

$ ls tools/board/config.alios.mk3080 config.arm-linux.demo config.ubuntu.x86

文档版本:20200417 261

Page 274: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

编辑配置文件

在这一步, 需要设置编译选项和工具链, 以及跳过编译的目录

$ vim tools/board/config.arm-linux.demo

CONFIG_ENV_CFLAGS = \ -D_PLATFORM_IS_LINUX_ \ -Wall \ -DNO_EXECUTABLES

CONFIG_ENV_LDFLAGS = \ -lpthread -lrt

OVERRIDE_CC = arm-linux-gnueabihf-gccOVERRIDE_AR = arm-linux-gnueabihf-arOVERRIDE_LD = arm-linux-gnueabihf-ld

CONFIG_wrappers :=

注意:

上面的最后1行表示跳过对wrappers目录的编译,以及-DNO_EXECUTABLES不要产生可执行程

序。在编译未被适配平台的库时在最初是必要的, 这样可以避免产生过多的错误。

注:上述配置文件的内容从某些浏览器复制出来之后将会丢失空

行。

选择配置文件

$ make reconfig

SELECT A CONFIGURATION:

1) config.alios.mk30802) config.arm-linux.demo3) config.ubuntu.x86

#? 2

SELECTED CONFIGURATION:

VENDOR : arm-linux

MODEL : demo

262 文档版本:20200417

Page 275: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

交叉编译产生库文件libiot_sdk.a

注: 本步骤不编译HAL, 只是为了验证配置文件中的交叉编译参数

是否正确, 如果出现错误请对配置文件再次进行修改, 直到编译成

$ make

BUILDING WITH EXISTING CONFIGURATION:

VENDOR : arm-linux

MODEL : demo

[CC] infra_timer.o <= ...[CC] infra_json_parser.o <= ...[CC] infra_preauth.o <= ...

获取交叉编译的产物, 包括静态库和头文件

$ ls -1 output/release/lib/libiot_sdk.alibiot_tls.a

这里, libiot_sdk.a文件就是编译好的物联网套件SDK, 已经是ELF 32-bit LSB relocatable, ARM,

EABI5 version 1 (SYSV)格式, 也就是arm-linux格式的交叉编译格式了

另外, libiot_tls.a是一个裁剪过的加解密库, 您可以选择使用它, 也可以选择使用平台自带的加解密库,

以减小最终固件的尺寸

$ ls -1 output/release/include/

dev_model_api.hdev_sign_api.hinframqtt_api.h

这里, dev_sign_api.h就是使用SDK中"设备签名"功能需要包含的头文件, 类似mqtt_api.h是使

用SDK中"MQTT上云"功能需要的, infra下的头文件也请加入编译搜索路径

开发未适配平台的HAL层

对于实现平台抽象层接口 HAL_XXX_YYY() 的库 libiot_hal.a, 不限制其编译和产生的方式

但是如果你愿意的话, 当然仍然可以借助物联网套件设备端C-SDK的编译系统来开发和产生它

文档版本:20200417 263

Page 276: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

复制一份HAL层实现代码

注: 在 wrappers/os 下需要创建一个与 tools/board/confg.XXX

.YYY 中的 XXX 一样的目录用于存放HAL实现

由于目标平台为arm-linux,因此可以复制Ubuntu下面的HAL实现,下面是操作示例:

$ cd wrappers/os/

$ lsfreertos nos nucleus ubuntu

wrappers/os$ cp -rf ubuntu arm-linux

wrappers/os$ rm -f arm-linux/HAL_UART_linux.c

wrappers/os$ lsarm-linux freertos nos nucleus ubuntu

wrappers/os$ tree -A arm-linux/arm-linux/+-- HAL_AWSS_linux.c+-- HAL_Crypt_Linux.c+-- HAL_FS_Linux.c+-- HAL_KV_linux.c+-- HAL_OS_linux.c+-- HAL_TCP_linux.c+-- HAL_UDP_linux.c

打开之前被关闭的编译开关

$ vim tools/board/config.arm-linux.demo

CONFIG_ENV_CFLAGS = \ -D_PLATFORM_IS_LINUX_ \ -Wall\ -DNO_EXECUTABLES

CONFIG_ENV_LDFLAGS = \ -lpthread -lrt

OVERRIDE_CC = arm-linux-gnueabihf-gccOVERRIDE_AR = arm-linux-gnueabihf-arOVERRIDE_LD = arm-linux-gnueabihf-ld

# CONFIG_wrappers :=

可以看到在CONFIG_wrappers :=这一行前添加了一个#符号, 代表这一行被注释掉了, wrappers将会

进入编译过程

尝试交叉编译被复制的HAL层代码

$ make reconfig

264 文档版本:20200417

Page 277: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

SELECT A CONFIGURATION:

1) config.alios.mk30802) config.arm-linux.demo3) config.ubuntu.x86

#? 2

SELECTED CONFIGURATION:

VENDOR : arm-linuxMODEL : demo

...

$ make

可以看到我们进展的十分顺利, 被复制的代码 wrappers/os/arm-linux/*.c 直接编译成功了, 产生了

arm-linux 格式的 libiot_hal.a

交叉编译样例程序

这样有了libiot_hal.a, libiot_tls.a, 以及libiot_sdk.a, 已经可以尝试交叉编译样例的可执行程序, 并

在目标嵌入式硬件开发板上运行一下试试了

方法是去掉 config.arm-linux.demo 里面的 -DNO_EXECUTABLES开关, 使得*/examples/目录下

的样例源码被编译出来

注:删掉-DNO_EXECUTABLES开关时记得把上面一行-Wall后面的''符号也删掉

修改后的config.arm-linux.demo内容如下所示:

$ vi tools/board/config.arm-linux.demo

CONFIG_ENV_CFLAGS = \ -D_PLATFORM_IS_LINUX_ \ -Wall

CONFIG_ENV_LDFLAGS = \ -lpthread -lrt

OVERRIDE_CC = arm-linux-gnueabihf-gccOVERRIDE_AR = arm-linux-gnueabihf-arOVERRIDE_LD = arm-linux-gnueabihf-ld

# CONFIG_wrappers :=

文档版本:20200417 265

Page 278: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

可以看到在 -DNO_EXECUTABLES 开关从 CONFIG_ENV_CFLAGS 中去掉了, 例子可执行程序进入了

编译范围

重新载入配置文件, 交叉编译可执行程序

$ make reconfig

$ make

如果有如下的编译输出, 则代表 mqtt-example 等一系列样例程序已经被成功的编译出来, 它们存放

在 output/release/bin 目录下

[LD] dev-sign-example <= ...[LD] mqtt-example <= ...[LD] linkkit-example-solo <= ...

$ cd output/release/bin/

$ lsdev-sign-example linkkit-example-solo mqtt-example

$ file *

dev-sign-example: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked ...

linkkit-example-solo: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked ...

mqtt-example: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked ...

可以用file命令验证, 这些可执行程序确实是交叉编译到 arm-linux 架构上的

尝试运行样例程序

接下来, 您就可以把样例程序例如mqtt-example, 用SCP, TFTP或者其它方式, 拷贝下载到您的目标开

发板上运行调试了

• 如果一切顺利, 样例程序和同样例程在 Ubuntu 上运行效果相同, 则证明 wrappers/os/arm-

linux 部分的HAL层代码工作正常

• 如果样例程序运行起来, 和同样例程在 Ubuntu 上运行效果不同, 则需要再重点修改调试HAL实现

• 也就是指 wrappers/os/arm-linux 目录的HAL层代码, 因为这些代码是我们从 Ubuntu 主机部分

复制的, 完全可能并不适合 arm-linux

如此反复直到确保 libiot_hal.a 的开发没问题为止

266 文档版本:20200417

Page 279: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.5 基于代码抽取时的移植说明对于使用KEIL、IAR进行设备开发的用户来说,不能使用make的方式编译SDK。此时用户可以配置需

要的SDK功能,使用SDK提供的抽取工具将相应的代码抽取出来,然后将源文件添加到开发工具中的

项目后进行编译; 对于使用Linux作为开发环境的用户,也可以使用本方式将代码抽取出来之后进行

交叉编译。

本文将以获取 MQTT上云 和 OTA固件升级 能力为例, 描述在 Windows 开发主机上的SDK移植过程

设备端的整体开发过程如下所示

以下是详细步骤讲解

SDK功能配置

SDK中有各种功能模块, 用户需要决定需要使用哪些功能, 在本例

中假设用户需要"MQTT上云"和"OTA固件下载"的功能

在SDK的根目录双击 config.bat 脚本运行, 弹出如下的功能选择界面(相当于Ubuntu16.04 64位主机

上的 make menuconfig 命令)

文档版本:20200417 267

Page 280: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 按下空格键可以选中或者失效某个功能, 使用小键盘的上下键来在不同功能之间切换

• 如果想知道每个选项的具体含义, 先用方向键将高亮光条移到那个选项上, 再按键盘上的"h"按键,

将出现帮助文本, 对选项进行详细说明

比如:

• 如果编译环境有自带标准头文件<stdint.h>, 请使能选项 PLATFORM_HAS_STDINT

• 如果目标系统上运行有嵌入式操作系统, 请使能选项 PLATFORM_HAS_OS

• 如果目标系统上支持 malloc 和 free 这样的动态内存管理能力, 请使能选项 PLATFORM_H

AS_DYNMEM

在本例中, 我们需要"MQTT上云"和"OTA固件下载"的功能, 所以需要选中

• FEATURE_MQTT_COMM_ENABLED: 对应"MQTT上云"功能

• FEATURE_OTA_ENABLED: 对应"OTA固件下载"功能

268 文档版本:20200417

Page 281: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

然后将光标移动到窗口底部的<Exit>上, 在随后弹出的保存对话框中选<Yes>存盘退出配置界面

SDK代码抽取

经过上面的步骤, SDK根目录下的 make.settings 功能配置文件的内容就会发生变化, 对应到用户所

选择的功能,如下所示:

FEATURE_MQTT_COMM_ENABLED=yFEATURE_MQTT_DEFAULT_IMPL=y# FEATURE_MQTT_PRE_AUTH is not setFEATURE_MQTT_DIRECT=y...FEATURE_OTA_ENABLED=y

可以注意到其中对应所选功能点的开关 FEATURE_MQTT_COMM_ENABLED 和 FEATURE_OT

A_ENABLED 都已被设置为 y, 表示打开了

接下来运行代码抽取工具 extract.bat, 该脚本运行之后的界面如下所示:

文档版本:20200417 269

Page 282: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

抽取后的代码说明

如同 config.bat 脚本的输出是 make.settings 文件, extract.bat 脚本的输入是 make.settings, 输

出是 output 文件夹

点击进去, 观察它的内容。output目录结构如下

output/+-- eng| +-- certs| +-- dev_model| +-- dev_sign| +-- infra| +-- mqtt| +-- ota| +-- wrappers| +-- external_libs+-- examples

其中 output/eng 目录就对应的是SDK相关功能抽取出来的代码, output/example对应使用SDK中

API接口的例子程序

文件或目录 说明

output/eng 对应SDK和支撑SDK的HAL接口

270 文档版本:20200417

Page 283: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

文件或目录 说明

output/eng/infra 不对应到某个具体的功能点, 表示"基础", 但是内容的多少会随着被选择的功能点多少而变化

output/eng/certs 不对应到某个具体的功能点, 存放着验证阿里云IoT服务端的根证书, 使能TLS传输时出现

output/eng/xxx 对应当前被选中的 xxx 功能的实现源码, 其中output/eng/xxx/xxx_api.h列出了这个功能的API

output/example/xxx 对应当前被选中的 xxx 功能的例子程序, 演示了如何用这个功能的API编写业务逻辑

在本例中, eng下面的目录如下所示:

这些功能点的例子程序都在 output/examples 文件夹

文档版本:20200417 271

Page 284: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

对接HAL接口或者wrapper接口

SDK运行时对外界所需要的依赖都以 HAL_XXX或者 wrapper_xxx进行定义,并放于文件output\eng

\wrappers\wrapper.c中,用户需要对其中的函数进行实现。

对每个 HAL_XXX 接口都有详细的注释和文档, 用户可以参考SDK根目录下的wrappers子目录中的

wrapper参考实现。

其它

抽取出来的代码使用make进行编译

用户也可能使用 GNU Make对抽取出来的代码进行编译, 因此在抽取出来的目录下仍然提供了一个示

例的makefile, make之后将会生成以下内容:

二进制文件 说明 产生方式

libiot_sdk.a SDK主库文件, 提供所有形如 IOT_XXX 的用户API

从 output/eng 下除了 output/wrapper/* 的目录产生

libiot_hal.a 支撑SDK的HAL库, 提供形如 HAL_XXX 的底层接口

从 output/eng/wrappers 下源文件产生, 其中 output/eng/wrappers/wrapper.c 需要用户填写

272 文档版本:20200417

Page 285: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

二进制文件 说明 产生方式

xxx-example 功能点的例子程序 从 output/examples/xxx 下源文件产生, 需要通过 output 目录下运行 make prog 命令编译

使用C++编译器编译时错误的处理

C++编译器在编译的时候判断比gcc判断更加严格,如果编译的时候出错,请编译时:

增加 -fpermissive -w, 去掉 -ansi -Wdeclaration-after-statement

总结

以图中红色文字表示用户执行的动作, 用绿色文字表示用户得到的产物, 则这个过程可用下图表示为

图中左上角是移植过程的开始, 到右下角是移植过程的结束, 以获得目标设备架构的二进制库

libiot_sdk.a 和 libiot_hal.a 为标志

到此为止整个SDK的抽取都已经讲解完毕, 您可以将 output/eng 下的所有目录加入自己的工程中编

译和集成, 并参考 output/examples 下的例程开始调用SDK提供的API了

1.2.1.5.6 MCU上集成SDK

文档版本:20200417 273

Page 286: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.6.1 MCU+支持TCP的模组应用场景: 设备的硬件由一个MCU加上一个通信模组构成, 设备的应用逻辑运行在MCU上, 模组上支持

了TCP但是并不支持MQTT, MCU通过模组提供的AT指令来控制模组何时连接云端服务以及收发数据

本示例中 示例app + SDK + TCP模组驱动 一起消耗大概11KB内存

对于这样的场景, 设备厂商需要将Link Kit SDK集成并运行在MCU上, 让Link Kit SDK通过通信模组连

接到阿里云物联网平台

文档目标

下面的文档关注于讲解用户如何把SDK移植到MCU, 并与通信模组协作来与阿里云物联网平台通信. 为

了简化移植过程, 下面的文档在MCU上以开发一个基础版产品作为案例进行讲解, ++如果用户需要在

MCU上使用SDK的其它功能, 可以在MCU上将基础版的example正确运行之后, 再重新配置SDK, 选中

其它功能再进行产品功能开发. ++

设备端开发过程

如何在阿里云物联网平台创建基础版产品和设备请参见产品创建(基础版)

设备端的开发过程如下所示:

SDK配置与代码抽取

SDK中有各种功能模块, 用户需要决定:

274 文档版本:20200417

Page 287: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 需要使用哪些功能(SDK配置)

SDK提供了配置工具用于配置需要使能哪些功能, 每个功能的配置选项名称类似FEATURE_MQTT_XXX

, 下面的章节中会讲解具体有哪些功能可供配置

• SDK如何与外部模组进行数据交互

SDK使用MQTT与阿里云物联网平台通信, 对于模组只支持TCP的情况, 意味着MCU上需要使能SDK自

带的MQTT Client, 由MQTT Client将用户数据封装成MQTT协议之后通过通信模组上的TCP模块将数据

发送到阿里云物联网平台,如下图所示:

MQTT Client与给模组协作的时候, 开发者需要编写一个TCP连接管理模块去实现如下功能:

• 控制模组发起到阿里云物联网平台的TCP连接, 并记录模组返回的TCP连接ID

• 当MQTT Client发送数据时, 将数据通过MQTT Client创建的模组TCP连接ID进行数据发送

• 接收来自模组的字符流数据, 只有是从MQTT Client建立的TCP连接ID中的数据才能发送给MQTT

Client

• 如果MQTT Client接收和处理数据的速度慢于模组发送数据给MCU的速度, 开发者还需要将数据进

行缓存以避免数据丢失

该TCP连接管理模组与SDK/TCP模组关系如下图所示:

Link Kit SDK中包含了一个模组TCP连接和数据缓存的模块, 称为AT TCP, 如果开发者在MCU上尚未实

现这样一个模组TCP连接和数据缓存的模块, 可以使用SDK提供的AT TCP

MCU与模组之间通常使用UART进行连接, 因此开发者需要开发代码对UART进行初始化, 通过UART接

收来自模组的数据, 由于UART是一个字符一个字符的接收数据, 因此开发者还需要对收到的数据组装

文档版本:20200417 275

Page 288: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

并判断AT指令是否承载TCP数据, 如果是才能将TCP数据发送给TCP连接管理模块. 这个模块与SDK/模

组的关系如下图所示:

Link Kit SDK中包含了一个AT解析的模块, 称为AT Parser, 如果开发者尚未实现这样的一个功能模块,

可以使能Link Kit SDK中的AT Parser模块以减少开发工作量

SDK与模组对接结构说明

下面是SDK与TCP模组的可能对接方式的图示, 以及相关的配置选项:

276 文档版本:20200417

Page 289: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

上图中SDK外部的蓝色配置选项表示该选项使能后将会使能的SDK功能模块, 每根红色虚线代表一种

可能的SDK与模组的对接方式, HAL表示该模块与外部模块交互的函数定义:

配置选项 说明 可选项

FEATURE_MQTT_COMM_ENABLED

是否需要为MQTT提供API 必选

FEATURE_MQTT_DEFAULT_IMPL

使能后将包含SDK中的MQTT实现, 并提供TCP HAL函数用于在TCP上收发MQTT数据

必选

FEATURE_MQTT_ATM_ENABLED

是否使能SDK中的ATM模块 可选

FEATURE_AT_TCP_ENABLED 是否使能AT TCP模块, 当本模块被使能后, AT TCP将会提供TCP HAL实现, 也就是说开发者无需再实现TCP HAL, 但是开发者需要实现AT TCP HAL

可选

FEATURE_AT_PARSER_ENABLED

是否使能AT Parser模块, 当本模块被使能后, AT Parser将会提供AT TCP HAL实现, 也就是说开发者无需再实现AT TCP HAL, 但是开发者需要实现AT Parser HAL

可选

配置SDK

SDK包含的功能较多, 为了节约对MCU RAM/Flash资源的消耗, 用户需要根据自己的产品功能定义需

要SDK中的哪些功能

运行配置命令

• Linux系统

进入SDK的根目录下, 运行命令

make menuconfig

• Windows系统

运行SDK根目录下的config.bat

config.bat

文档版本:20200417 277

Page 290: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

使能需要的SDK功能

运行上面的命令之后, 将会跳出下面的功能配置界面. 按下空格键可以选中或者失效某个功能, 使用小

键盘的上下键来在不同功能之间切换. 如果想知道每个选项的具体含义, 先用方向键将高亮光条移到那

个选项上, 再按键盘上的"h"按键, 将出现帮助文本, 说明选项是什么含义, 打开了和关闭了意味着什么

如果编译环境有自带标准头文件<stdint.h>, 请使能选项

• PLATFORM_HAS_STDINT

如果目标系统上运行有嵌入式操作系统, 请使能选项

• PLATFORM_HAS_OS

本场景中由于模组支持TCP但是不支持MQTT, 因此必须使能下面两项配置:

• FEATURE_MQTT_COMM_ENABLED, 使用阿里SDK提供的MQTT API与云端通信

• FEATURE_MQTT_DEFAULT_IMPL, 使用阿里SDK中自带的MQTT Client实现, 用户需要实现相关的

TCP连接的创建/连接/数据收发过程

• FEATURE_ATM_ENABLED 如果希望使用阿里提供的AT TCP或者AT Parser,请使能本选项。当本

模块使能之后, 还会出现是否使能AT TCP的配置选项:

278 文档版本:20200417

Page 291: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

开发者可以根据产品的实际情况选择是否使能ATM以及AT TCP. 如果开发者使能了ATM, 但是开发者没

有用于AT收发/解析的框架, 可以选择使用at_parser框架(非必须):

• FEATURE_AT_PARSER_ENABLED

SDK基于at_parser提供了已对接示例, 如果模组是sim800 2G模组或者mk3060 Wi-Fi模组, 可以进行

进一步选择模组的型号, 可以让SDK将相应的HAL实现也包含在抽取的代码中. 如果不需要对接示例,

请忽略该步骤

完整的配置开关说明表格如下, 但最终解释应以上面提到的"h"按键触发文本为准

文档版本:20200417 279

Page 292: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

配置开关 说明

PLATFORM_HAS_STDINT 告诉SDK当前要移植的嵌入式平台是否有自带标准头文件<stdint.h>

PLATFORM_HAS_OS 目标系统是否运行某个操作系统

FEATURE_MQTT_COMM_ENABLED MQTT 长连接功能, 打开后将使SDK提供MQTT网络收发的能力和接口

FEATURE_MQTT_DEFAULT_IMPL SDK内包含的MQTT Client实现, 打开则表示使用SDK内置的MQTT客户端实现

FEATURE_ASYNC_PROTOCOL_STACK 对于使用SDK内置的MQTT客户端实现的时候, 需要用户实现TCP相关的HAL, 这些HAL的TCP发送数据/接收数据的定义是同步机制的, 如果目标系统的TCP基于异步机制, 可以使能该开关实现SDK从同步到异步机制的转换

FEATURE_DYNAMIC_REGISTER 动态注册能力, 即设备端只保存了设备的ProductKey和ProductSecret和设备的唯一标识,通过该功能从物联网平台换取DeviceSecret

FEATURE_DEVICE_MODEL_ENABLE 使能设备物模型编程相关的接口以及实现

FEATURE_DEVICE_MODEL_GATEWAY 网关的功能以及相应接口

FEATURE_THREAD_COST_INTERNAL 为收包启动一个独立线程

FEATURE_SUPPORT_TLS 标准TLS连接, 打开后SDK将使用标准的TLS1.2安全协议连接服务器

FEATURE_SUPPORT_ITLS 阿里iTLS连接, 打开后SDK将使用阿里自研的iTLS代替TLS建立安全连接

FEATURE_ATM_ENABLED 如果系统是使用MCU+外接模组的架构, 并且SDK运行在MCU上, 必须打开该选项, 然后进行配置

FEATURE_AT_MQTT_ENABLED 如果MCU连接的通信模组支持MQTT AT, 则使用该选项

FEATURE_AT_PARSER_ENABLED 如果用户需要使用SDK提供的AT收发/解析的框架, 则可以使用该选项

FEATURE_AT_MQTT_HAL_ICA 基于at_parser的ICA MQTT AT对接示例

FEATURE_AT_MQTT_HAL_SIM800 基于at_parser的SIM800 MQTT对接示例

使能需要的SDK配置后, 保持配置并退出SDK配置工具

抽取选中功能的源代码

运行SDK根目录下的extract.bat(Linux下运行extract.sh), 客户选中的功能所对应的代码将会被放置

到文件夹output, 如下图所示:

280 文档版本:20200417

Page 293: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

实现HAL对接函数

Link Kit SDK被设计为可以在不同的操作系统上运行, 或者甚至在不支持操作系统的MCU上运行, 因此

与系统相关的操作被定义成一些HAL函数, 需要客户进行实现. 另外, 由于不同的通信模组支持的AT指

令集不一样, 所以与通信模组上TCP相关的操作也被定义成HAL函数需要设备开发者进行实现

由于不同的用户使能的SDK的功能可能不一样, 因此需要对接的HAL函数会不一样, 设备开发者只

需要实现位于文件output/eng/wrappers/wrapper.c中的HAL函数. 下面对所有可能出现在文件

wrapper.c的HAL函数进行讲解:

MCU系统相关HAL

必须实现函数:

__ __ 函数名 说明

1 HAL_Malloc 对应标准C库中的malloc(), 按入参长度开辟一片可用内存, 并返回首地址

2 HAL_Free 对应标准C库中的free(), 将入参指针所指向的内存空间释放, 不再使用

3 HAL_Printf 对应标准C库中的printf(), 根据入参格式字符串将字符文本显示到终端

文档版本:20200417 281

Page 294: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

__ __ 函数名 说明

4 HAL_Snprintf 类似printf, 但输出的结果不再是显示到终端, 而是存入指定的缓冲区内存

5 HAL_UptimeMs 返回一个uint64_t类型的数值,表达设备启动后到当前时间点过去的毫秒数

6 HAL_SleepMs 按照指定入参的数值, 睡眠相应的毫秒, 比如参数是10, 那么就会睡眠10毫秒

对以上函数若需了解更多细节, 可访问SDK官方文档页面

OS相关可选函数

如果MCU没有运行OS, 或者SDK的MQTT API并没有在多个线程中被调用, 以下函数可以不用修改

wrapper.c中相关的函数实现. 在有OS场景下并且MQTT API被APP在多个线程中调用, 则需要用户对

接以下函数:

__ __ 函数名 说明

1 HAL_MutexCreate 创建一个互斥锁, 返回值可以传递给HAL_MutexLock/Unlock

2 HAL_MutexDestroy 销毁一个互斥锁, 这个锁由入参标识

3 HAL_MutexLock 申请互斥锁, 如果当前该锁由其它线程持有, 则当前线程睡眠,否则继续

4 HAL_MutexUnlock 释放互斥锁, 此后当前在该锁上睡眠的其它线程将取得锁并往下执行

5 HAL_SemaphoreCreate 创建一个信号量, 返回值可以传递给HAL_SemaphorePost/Wait

6 HAL_SemaphoreDestroy 销毁一个信号量, 这个信号量由入参标识

7 HAL_SemaphorePost 在指定的计数信号量上做自增操作, 解除其它线程的等待

8 HAL_SemaphoreWait 在指定的计数信号量上等待并做自减操作

282 文档版本:20200417

Page 295: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

__ __ 函数名 说明

9 HAL_ThreadCreate 根据配置参数创建thread

对以上函数若需了解更多细节, 可访问SDK官方文档页面

TCP相关HAL

如果用户未选择ATM, 用户适配时调用模组提供的TCP AT指令实现四个TCP HAL函数. 下面是对这些函

数的说明, 也可访问SDK官方文档页面了解更多说明

** 函数名 说明

1 HAL_TCP_Establish 建立一个TCP连接 注意: + 入参host是一个域名, 需要转换为IP地址 + 返回值是tcp的socket号

2 HAL_TCP_Destroy 关闭tcp连接, 入参是HAL_TCP_Establish的返回值,返回值0表示成功

3 HAL_TCP_Write 通过TCP连接发送数据 注意: +该函数传入了一个超时时间, 如果超时仍未将数据发送结束那么函数也需要返回. + 如果TCP连接已断开, 需要返回一个小于0的负数

4 HAL_TCP_Read 在指定的时间内读取数据并返回, 该函数的入参中指定了可接收的数据的最大长度, 如果从TCP中读取到该最大长度的数据,那么可以立即返回

AT TCP相关HAL

如果用户选择使用ATM以及AT TCP, 并且未使能AT Parser, 用户需要实现下面表格中的HAL函数. 下面

是对这些函数的说明:

** 接口名 说明

1 HAL_AT_CONN_Init 该接口需要对通信模组进行相关初始化, 使通信模组达到可以工作的状态

2 HAL_AT_CONN_Deinit 该接口需要提供对通信模组的去初始化操作

文档版本:20200417 283

Page 296: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

3 HAL_AT_CONN_Start 该接口需要模组启动一次连接.上层传给底层的参数为一个结构体指针at_conn_t, 其参数说明如下: fd: 每个连接对应的句柄. type: 建立连接的类型(如TCP_client), 见at_wrapper.h. addr: 对端ip或者域名. r_port: 远端端口号. l_port: 本地端口号. tcp_keep_alive: tcpkeep alive的时间

4 HAL_AT_CONN_Close 该接口关闭模组的一个连接.入参说明如下: fd: 需要关闭的socket句柄. remote_port: 对端端口号, 该参数为可选参数,小于0时为无效参数.

5 HAL_AT_CONN_Send 该接口通过模块发送数据的接口, 该接口为阻塞接口, 直到模组通知底层控制模块数据发送成功才会返回. 入参说明如下: fd: 发送数据所操作的句柄 data:待发送数据的指针 len: 待发送数据的长度 remote_ip[16], 对端ip地址, 为可选参数, 为NULL时无效 remote_port: 对端端口号, 为可选参数, 小于0时无效

6 HAL_AT_CONN_DomainToIp 该接口提供获取对应域名ip地址的功能, 注意: 1/即使该域名对应多个ip, 也只会返回一个ip地址. 2/目前该接口只需要支持ipv4. 入参说明如下: domain:域名信息 ip[16]: 点格式的ip字符串, 目前只支持ipv4

AT TCP HAL对接示例

(1)HAL_AT_CONN_Init

该函数完成HAL层数据初始化. 下面的代码示例中, 创建了容量为LINK_ID_MAX的TCP连接数组, 用于

对应模组上创建的TCP连接. 用户还需要在此处完成与模组必要的交互, 例如sim800模组对接时需要

附着网络/获取ip地址等

typedef struct link_s { int fd; ....} link_t;

284 文档版本:20200417

Page 297: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

static link_t g_link[LINK_ID_MAX];int HAL_AT_CONN_Init(void){ int link;

memset(g_link, 0, sizeof(g_link)); for (link = 0; link < LINK_ID_MAX; link++) { g_link[link].fd = -1; }

... inited = true; return 0;}

(2)HAL_AT_CONN_Deinit

该函数完去初始化, 将HAL_AT_CONN_Init()中分配的资源释放. 下面的示例中只是简单的将inited变

量设置为false:

int HAL_AT_CONN_Deinit(void){ if (!inited) { return 0; } inited = false; return 0;}

(3)HAL_AT_CONN_Start

该函数用于建立TCP连接. 下面的示例代码主要包括从g_link数组中获得空闲的TCP连接元素/记录该

连接的地址/端口等信息, 向模组发送拼接生成的建立TCP连接的AT指令. 用户需要将该函数实现修改

为实际使用的模组提供的AT指令, 并对返回数据进行相应处理

int HAL_AT_CONN_Start(at_conn_t *c){ int link_id; for (link_id = 0; link_id < LINK_ID_MAX; link_id++) { if (g_link[link_id].fd >= 0) { continue; } else { g_link[link_id].fd = c->fd; break; } } ... /* 拼接AT命令 */ snprintf(cmd, START_CMD_LEN, "%s=%d,%s,%s,%d", START_CMD, link_id, start_cmd_type_str[c->type], c->addr, c->r_port); .... /* 发送AT命令 */ at_send_wait_reply(cmd, strlen(cmd), true, out, sizeof(out), NULL); LOGD(TAG, "The AT response is: %s", out); if (strstr(out, CMD_FAIL_RSP) != NULL) { goto err;

文档版本:20200417 285

Page 298: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

return 0;err: // error handle}

(4)HAL_AT_CONN_Close

该函数用于关闭TCP连接. 下面的示例代码主要包括记录向模组发送动态生成的AT指令, 然后删除

linkid与fd的映射. 其中, fd_to_linkid()是fd向linkid转换函数

int HAL_AT_CONN_Close(int fd, int32_t remote_port){ int link_id; char cmd[STOP_CMD_LEN] = {0}, out[64]; link_id = fd_to_linkid(fd); if (link_id < 0 || link_id >= LINK_ID_MAX) { LOGE(TAG, "No connection found for fd (%d) in %s", fd, __func__); return -1; } snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link_id); LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd); at_send_wait_reply(cmd, strlen(cmd), true, out, sizeof(out), NULL); LOGD(TAG, "The AT response is: %s", out); if (strstr(out, CMD_FAIL_RSP) != NULL) { LOGE(TAG, "%s %d failed", __func__, __LINE__); goto err; } ... g_link[link_id].fd = -1;}

(5)HAL_AT_CONN_Send

该函数用于向模组发送数据, 主要工作是向模组发送拼接生成AT命令与数据. 下面的示例代码是向模

组上指定的TCP socket发送数据, 用户需要将AT指令修改为实际连接模组对应的AT指令以及进行相应

处理

int HAL_AT_CONN_Send(int fd, uint8_t *data, uint32_t len, char remote_ip[16], int32_t remote_port, int32_t timeout){ int link_id; char cmd[SEND_CMD_LEN] = {0}, out[128] = {0}; if (!data) { return -1; } link_id = fd_to_linkid(fd); if (link_id < 0 || link_id >= LINK_ID_MAX) { LOGE(TAG, "No connection found for fd (%d) in %s", fd, __func__); return -1; } /* AT+CIPSEND=id, */

286 文档版本:20200417

Page 299: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

snprintf(cmd, SEND_CMD_LEN - 1, "%s=%d,", SEND_CMD, link_id); /* [remote_port,] */ if (remote_port >= 0) { snprintf(cmd + strlen(cmd), 7, "%d,", remote_port); } at_send_data_2stage((const char *)cmd, (const char *)data, len, out, sizeof(out));}

(6)HAL_AT_CONN_DomainToIp

该函数用于域名解析, 向模组发送动态生成的查询命令后, 根据已知格式解析回复

int HAL_AT_CONN_DomainToIp(char *domain, char ip[16]){ char cmd[DOMAIN_CMD_LEN] = {0}, out[256] = {0}, *head, *end; snprintf(cmd, DOMAIN_CMD_LEN - 1, "%s=%s", DOMAIN_CMD, domain);

/* 发送查询命令 */ at_send_wait_reply(cmd, strlen(cmd), true, out, sizeof(out), NULL); LOGD(TAG, "The AT response is: %s", out); if (strstr(out, AT_RECV_SUCCESS_POSTFIX) == NULL) { LOGE(TAG, "%s %d failed", __func__, __LINE__); return -1; } /* 根据已知格式解析回复 */ ...}

调用接收函数

用户在AT HAL层收到数据后需要调用API接口IOT_ATM_Input(见atm/at_api.h), 将数据交付给上层

void handle_recv_data(){ struct at_conn_input param; ... /* 读取AT指令中数据长度信息 */ len = atoi(reader); if (len > MAX_DATA_LEN) { LOGE(TAG, "invalid input socket data len %d \r\n", len); return; }

/*分配接收buffer, 用户也可以直接使用一个静态数组用于数据接收*/ recvdata = (char *)aos_malloc(len); if (!recvdata) { LOGE(TAG, "Error: %s %d out of memory, len is %d. \r\n", __func__, __LINE__, len); return; }

/* 读取数据 */ ret = at_read(recvdata, len); if (ret != len) { LOGE(TAG, "at read error recv %d want %d!\n", ret, len); goto err; }

if (g_link[link_id].fd >= 0) { param.fd = g_link[link_id].fd;

文档版本:20200417 287

Page 300: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

param.data = recvdata; param.datalen = len; param.remote_ip = NULL; param.remote_port = 0;

/* 向上层交付数据 */ if (IOT_ATM_Input(&param) != 0) { at_conn_hal_err(" %s socket %d get data len %d fail to post to at_conn, drop it\n", __func__, g_link[link_id].fd, len); } } ...}

其中, struct at_conn_input定义见at_wrapper.h

struct at_conn_input { int fd; /* 数据上送需要操作的句柄 */ void *data; /* 接收到的数据(该部分内存由底层自行释放)*/ uint32_t datalen; /* 接收到的数据长度 */ char *remote_ip; /* 该数据的源地址, 为可选参数, 可以传入NULL(该部分内存由底层自行释放)*/ uint16_t remote_port; /* 该数据的源端口, 为可选参数, 可以传入0 */};

AT Parser相关HAL

如果选择了at_parser框架, 则需要对接以下四个UART HAL函数, 函数声明见at_wrapper.h. 如果用

户不使用at_parser框架请忽略该步骤

** 接口名 说明

1 HAL_AT_Uart_Init 该接口对UART进行配置(波特率/停止位等)并初始化

2 HAL_AT_Uart_Deinit 该接口对UART去初始化

3 HAL_AT_Uart_Send 该接口用于向指定的UART口发送数据

4 HAL_AT_Uart_Recv 该接口用于从底层UART buffer接收数据

产品相关HAL

下面的HAL用于获取产品的身份认证信息, 设备厂商需要设计如何在设备上烧写设备身份信息, 并通过

下面的HAL函数将其读出后提供给SDK:

__ __ 函数名 说明

1 HAL_GetProductKey 获取设备的ProductKey, 用于标识设备的产品型号

288 文档版本:20200417

Page 301: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

__ __ 函数名 说明

2 HAL_GetDeviceName 获取设备的DeviceName, 用于唯一标识单个设备

3 HAL_GetDeviceSecret 获取设备的DeviceSecret, 用于标识单个设备的密钥

对以上函数若需了解更多细节, 可访问SDK官方文档页面

代码集成

如果设备商的开发环境使用makefile编译代码, 可以将SDK抽取出来的代码加入其编译环境进行编译.

如果设备商使用KEIL/IAR这样的开发工具, 可以将SDK抽取出来的代码文件加入到IDE的工程中进行编

下面是将抽取出来的output目录复制到Linux下, 并在output目录下创建的一个makefile的示例

注: 配置时使能了ATM模块/使用AT TCP/AT Parser/并选择使用SIM800作为外接模组

SDK_PWD = $(shell pwd)/engSDK_DIRS = $(SDK_PWD)/dev_sign $(SDK_PWD)/atm $(SDK_PWD)/infra $(SDK_PWD)/mqtt $(SDK_PWD)/wrappers

SDK_SOURCES = $(foreach dir,$(SDK_DIRS),$(wildcard $(dir)/*.c))SDK_OBJS = $(patsubst %.c,%.o,$(SDK_SOURCES))

SDK_INC_DIRS = $(foreach dir, $(SDK_DIRS),-I$(dir) )

TARGET = testmqtt

all:eng/examples/mqtt_example_at.o $(SDK_OBJS) $(CC) -o $(TARGET) $(SDK_OBJS) eng/examples/mqtt_example_at.o

clean: rm -rf *.o $(TARGET) $(SDK_OBJS)

%.o:%.c $(CC) -c $(SDK_INC_DIRS) $< -o $@

注:

• 上面的makefile仅供参考, 用户配置SDK时选用的功能不一样会导致目录出现差别, 用户需要将除

了eng/examples外的目录加入编译系统/工具

• 用户如果复制该makefile使用, 在复制/粘贴时all/clean/%.o:%.c下一行的命令语句可能出现多

个空格/或者没有空格就直接是命令, 如果发现在命令前有空格需要将空格全部删除, 然后增加一个

Tab键, 以避免make出错

文档版本:20200417 289

Page 302: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参照example实现产品功能

如果要使用MQTT连云, 可参考抽取文件夹中的 eng/examples/mqtt_example_at.c . 设备厂商可以

将该文件复制到产品工程中, 对其进行修改后使用

该example将连接设备到阿里云, 订阅一个指定的topic并发送数据给该topic, 即设备上报的消息会被

物联网平台发送给设备, 下面是example的大概过程说明:

注意: 需要在云端将该topic从默认的权限从"订阅"修改为"发布和订阅", 如下图所示:

290 文档版本:20200417

Page 303: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

从程序入口的 main() 函数看起, 第一步是调用AT模块初始化函数IoT_ATM_Init(), 使模组处于ready

状态, 第二步是调用用户提供的HAL函数获取产品信息

int main(int argc, char *argv[]){ void * pclient = NULL; int res = 0; int loop_cnt = 0; iotx_mqtt_region_types_t region = IOTX_CLOUD_REGION_SHANGHAI; iotx_sign_mqtt_t sign_mqtt; iotx_dev_meta_info_t meta; iotx_mqtt_param_t mqtt_params;#ifdef ATM_ENABLED if (IOT_ATM_Init() < 0) { HAL_Printf("IOT ATM init failed!\n"); return -1; }#endif HAL_Printf("mqtt example\n"); memset(&meta, 0, sizeof(iotx_dev_meta_info_t)); HAL_GetProductKey(meta.product_key); HAL_GetDeviceName(meta.device_name); HAL_GetDeviceSecret(meta.device_secret);

注:

• 上面的三个HAL_GetXXX函数是获取设备的三元组信息, 设备厂商需要自己设计设备的三元组存放

的位置/并将其从指定位置读取出来

• 由于设备的唯一标识DeviceName/设备密钥DeviceSecret都是机密信息, 设备厂商在设计时可

以把相关信息加密后存放到Flash上, 在HAL函数里面将其解密后提供给SDK, 以避免黑客直接从

Flash里面读取设备的身份信息

接下来对MQTT连接参数进行指定, 客户可以根据自己的需要对参数进行修改:

/* Initialize MQTT parameter */ memset(&mqtt_params, 0x0, sizeof(mqtt_params)); mqtt_params.port = sign_mqtt.port; mqtt_params.host = sign_mqtt.hostname; mqtt_params.client_id = sign_mqtt.clientid; mqtt_params.username = sign_mqtt.username; mqtt_params.password = sign_mqtt.password;

文档版本:20200417 291

Page 304: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

mqtt_params.request_timeout_ms = 2000; mqtt_params.clean_session = 0; mqtt_params.keepalive_interval_ms = 60000; mqtt_params.read_buf_size = 1024; mqtt_params.write_buf_size = 1024; mqtt_params.handle_event.h_fp = example_event_handle; mqtt_params.handle_event.pcontext = NULL; pclient = IOT_MQTT_Construct(&mqtt_params);

通过调用接口 IOT_MQTT_Construct() 触发SDK连接云平台, 若接口返回值非NULL, 则连云成功

之后调用example_subscribe对一个指定的topic进行数据订阅:

res = example_subscribe(pclient);

example_subscribe的函数内容如下:

注:

• 设备商需要根据自己的产品设计, 订阅自己希望订阅的TOPIC, 以及注册相应的处理函数

• 订阅的topic的格式需要指定产品型号(product_key)以及设备标识(device_name), 如上图中第一

个橙色框中的格式

• 上图的第二个框展示了如何订阅一个指定的topic以及其处理函数

以下段落演示MQTT的发布功能, 即将业务报文上报到云平台:

while (1) { if (0 == loop_cnt % 20) {

292 文档版本:20200417

Page 305: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

example_publish(pclient); }

IOT_MQTT_Yield(pclient, 200);

loop_cnt += 1; }

下面是example_publish函数体的部分内容:

注:

• 上面的代码是周期性的将固定的消息发送给云端, 设备商需要根据自己的产品功能, 在必要的时候

才上传数据给物联网平台

• 客户可以删除main函数中example_publish(pclient)语句, 避免周期发送无效数据给到云端

• IOT_MQTT_Yield是让SDK去接收来自MQTT Broker的数据, 其中200毫秒是等待时间, 如果用户的

消息数量比较大/或者实时性要求较高, 可以将时间改小

功能调试

下面的信息截图以mqtt_example_at.c为例编写

如何判断设备已连接到阿里云

下面的打印是HAL_Printf函数将信息打印到串口后运行example的输出内容, 其中使用橙色圈选的信

息表明设备已成功连接到阿里云物联网平台:

文档版本:20200417 293

Page 306: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如何判断设备已成功发送数据到云端

登录阿里网物联网平台的商家后台, 选中指定的设备, 可以查看是否收到来自设备的消息, 如下图所示:

注: 上图中的内容只能看见消息发送到了哪个topic, 消息的内容并不会显示出来

如何判断设备已可成功接收来自云端数据

在商家后台的"下行消息分析"分析中可以看见由物联网平台发送给设备的消息:

294 文档版本:20200417

Page 307: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

也可在设备端查看是否已收到来自云端的数据, exmaple代码中收到云端发送的数据的打印信息如下

所示:

至此, SDK在MCU与模组之间的适配开发已结束, 用户可以进行产品业务功能的实现

参考示例

• STM32F103+SIM800C连接阿里云物联网平台

1.2.1.5.6.2 MCU+支持MQTT的模组应用场景: 设备的硬件由一个MCU加上一个通信模组构成, 设备的应用逻辑运行在MCU上, 通信模组支

持MQTT功能并提供AT指令给MCU使用, MCU控制模组连接云端服务以及收发数据

本示例中 示例app + SDK + 模组对接代码一起的RAM消耗为6KB

对于这样的场景, 设备厂商需要将Link Kit SDK集成并运行在MCU上, 让Link Kit SDK通过通信模组连

接到阿里云物联网平台

文档目标

下面的文档关注于讲解用户如何把SDK移植到MCU, 并与通信模组协作来与阿里云物联网平台通信.

为了简化移植过程, 下面的文档在MCU上以开发一个基础版产品作为案例进行讲解, 如果用户需要在

MCU上使用SDK的其它功能, 可以在MCU上将基础版的example正确运行之后, 再重新配置SDK, 选中

其它功能再进行产品功能开发。

文档版本:20200417 295

Page 308: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

设备端开发过程

如何在阿里云物联网平台创建基础版产品和设备请参见"创建产品(基础版)"

设备端的开发过程如下所示:

SDK配置与代码抽取

SDK中有各种功能模块, 用户需要决定:

• 需要使用哪些功能(SDK配置)

SDK提供了配置工具用于配置需要使能哪些功能, 每个功能的配置选项名称类似FEATURE_MQTT_XXX

, 下面的章节中会讲解具体有哪些功能可供配置

• SDK如何与外部模组进行数据交互

296 文档版本:20200417

Page 309: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

上图中的三根红色虚线代表SDK可以与MQTT模组进行数据交互的三种方式:

• MQTT Wrapper

MQTT Wrapper提供了接口函数定义用于与MQTT Client交互, 当MCU外接MQTT模组时可以通过实

现相关接口函数来驱动MQTT模组中的MQTT Client与阿里云物联网平台上的MQTT Broker/Server建

连/收发MQTT消息。开发者可以实现相关的wrapper函数来代码来驱动MQTT模组进行MQTT的连接,

无需使能ATM/AT MQTT/AT Parser等功能

• AT MQTT

当MQTT模组发送MQTT消息给MCU时, 如果模组发送给MCU的数据的速度超过了MCU上处理MQTT消

息的速度, 可能导致丢包, 因此SDK中实现了一个AT MQTT模块用于对收到的MQTT消息进行缓存。开

发者如果使能本模块, 本模块将提供MQTT Wrapper函数的实现, 开发者需要实现的函数将是AT MQTT

HAL中定义的函数, 在这些函数中驱动MQTT模组。

• AT Parser

MCU与模组之间通常使用UART进行连接, 因此开发者需要开发代码对UART进行初始化, 通过UART接

收来自模组的数据。由于UART是一个字符一个字符的接收数据, 因此开发者还需要对收到的数据组装

文档版本:20200417 297

Page 310: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

并判断AT指令是否承载MQTT数据, 如果是才能将MQTT数据发送给AT MQTT模块。SDK中提供了AT

Parser模块用于完成这些功能, 如果开发者尚未实现在UART上的数据收发/解析等功能, 可以使能AT

Parser功能来减少开发工作量

当开发者使能AT Parser后, AT Parser将会提供AT MQTT HAL的实现, 因此开发者需要实现的函数是

AT Parser HAL中定义的函数

配置SDK

SDK包含的功能较多, 为了节约对MCU RAM/Flash资源的消耗, 用户需要根据自己的产品功能定义需

要SDK中的哪些功能

运行配置命令

• Linux系统

进入SDK的根目录下, 运行命令

make menuconfig

• Windows系统

运行SDK根目录下的config.bat

config.bat

使能需要的SDK功能

运行上面的命令之后, 将会跳出下面的功能配置界面. 按下空格键可以选中或者失效某个功能, 使用小

键盘的上下键来在不同功能之间切换. 如果想知道每个选项的具体含义, 先用方向键将高亮光条移到那

个选项上, 再按键盘上的"h"按键, 将出现帮助文本, 说明选项是什么含义, 打开了和关闭了意味着什么

298 文档版本:20200417

Page 311: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如果编译环境有自带标准头文件<stdint.h>, 请使能选项

• PLATFORM_HAS_STDINT

如果目标系统上运行有嵌入式操作系统, 请使能选项

• PLATFORM_HAS_OS

请务必使能:

• FEATURE_MQTT_COMM_ENABLED, 用于让SDK提供MQTT API供应用程序调用, 并关闭

• FEATURE_MQTT_DEFAULT_IMPL, 该选项用于包含阿里提供的MQTT Client实现, 因为模组支持

MQTT Client, 所以关闭该选项

SDK连接MQTT模组有几种不同的对接方法, 为了简化对接, 本文档中使能

• FEATURE_ATM_ENABLED

该选项使能之后具有下面的子选项可供选择, 需要使能

• FEATURE_AT_MQTT_ENABLED

如果用户没有用于AT命令收发/解析的框架, 可以选择(非必须)使用at_parser框架:

• FEATURE_AT_PARSER_ENABLED

文档版本:20200417 299

Page 312: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

SDK基于at_parser提供了已对接示例, 如果模组是支持MQTT的sim800 2G模组或者支持ICA MQTT的

WiFi模组, 可以进行进一步选择相应选项, 这样开发的工作量将进一步减少. 如果不需要对接示例, 请

忽略该步骤

完整的配置开关说明表格如下, 但最终解释应以上面提到的"h"按键触发文本为准

配置开关 说明

PLATFORM_HAS_STDINT 告诉SDK当前要移植的嵌入式平台是否有自带标准头文件<stdint.h>

PLATFORM_HAS_OS 目标系统是否运行某个操作系统FEATURE_MQTT_COMM_ENABLEDMQTT长连接功能, 打开后将使SDK提供MQTT网络收发的能力和接口

FEATURE_MQTT_DEFAULT_IMPLSDK 内包含的MQTT Client实现, 打开则表示使用SDK内置的MQTT客户端实现

FEATURE_ASYNC_PROTOCOL_STACK 对于使用SDK内置的MQTT客户端实现的时候, 需要用户实现TCP相关的HAL, 这些HAL的TCP发送数据/接收数据的定义是同步机制的, 如果目标系统的TCP基于异步机制, 可以使能该开关实现SDK从同步到异步机制的转换

300 文档版本:20200417

Page 313: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

配置开关 说明

FEATURE_DYNAMIC_REGISTER 动态注册能力, 即设备端只保存了设备的ProductKey和ProductSecret和设备的唯一标识,通过该功能从物联网平台换取DeviceSecret

FEATURE_DEVICE_MODEL_ENABLE 使能设备物模型编程相关的接口以及实现FEATURE_DEVICE_MODEL_GATEWAY网关的功能以及相应接口

FEATURE_THREAD_COST_INTERNAL 为收包启动一个独立线程FEATURE_SUPPORT_TLS标准TLS连接, 打开后SDK将使用标准的TLS1.2安全协议连接服务器

FEATURE_SUPPORT_ITLS 阿里iTLS连接, 打开后SDK将使用阿里自研的iTLS代替TLS建立安全连接

FEATURE_ATM_ENABLED 如果系统是使用MCU+外接模组的架构, 并且SDK运行在MCU上, 必须打开该选项, 然后进行配置

FEATURE_AT_MQTT_ENABLED 如果MCU连接的通信模组支持MQTT AT, 则使用该选项

FEATURE_AT_PARSER_ENABLED 如果用户需要使用SDK提供的AT收发/解析的框架, 则可以使用该选项

FEATURE_AT_MQTT_HAL_ICA 基于at_parser的ICA MQTT AT对接示例

FEATURE_AT_MQTT_HAL_SIM800 基于at_parser的SIM800 MQTT对接示例

使能需要的SDK配置后, 保持配置并退出SDK配置工具。

抽取选中功能的源代码

运行SDK根目录下的extract.bat, 客户选中的功能所对应的代码将会被放置到文件夹output:

文档版本:20200417 301

Page 314: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

实现HAL对接函数

Link Kit SDK被设计为可以在不同的操作系统上运行, 或者甚至在不支持操作系统的MCU上运行, 因此

与系统相关的操作被定义成一些HAL函数, 需要客户进行实现. 另外, 由于不同的通信模组支持的AT指

令集不一样, 所以与通信模组上TCP相关的操作也被定义成HAL函数需要设备开发者进行实现。

由于不同的用户使能的SDK的功能可能不一样, 因此需要对接的HAL函数会不一样, 设备开发者只需要

实现位于文件output/eng/wrappers/wrapper.c中的HAL函数. 下面对可能出现在文件wrapper.c

的HAL函数进行讲解:

MCU系统相关HAL

必须实现函数:

序号 函数名 说明

1 HAL_Malloc 对应标准C库中的malloc(), 按入参长度开辟一片可用内存, 并返回首地址

2 HAL_Free 对应标准C库中的free(), 将入参指针所指向的内存空间释放

3 HAL_Printf 对应标准C库中的printf(), 根据入参格式字符串将字符文本显示到终端,如果用户无需在串口上进行调试,该函数可以为空

4 HAL_Snprintf 类似printf, 但输出的结果不再是显示到终端, 而是存入指定的缓冲区内存

5 HAL_UptimeMs 返回一个uint64_t类型的数值, 表达设备启动后到当前时间点过去的毫秒数

302 文档版本:20200417

Page 315: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

序号 函数名 说明

6 HAL_SleepMs 按照指定入参的数值, 睡眠相应的毫秒, 比如参数是10, 那么就会睡眠10毫秒

对以上函数若需了解更多细节, 可访问SDK官方文档页面

OS相关可选函数

如果MCU没有运行OS, 或者SDK的MQTT API并没有在多个线程中被调用, 以下函数可以不用修改

wrapper.c中相关的函数实现. 在有OS场景下并且MQTT API被APP在多个线程中调用, 则需要用户对

接以下函数:

序号 函数名 说明

1 HAL_MutexCreate

创建一个互斥锁, 返回值可以传递给HAL_MutexLock/Unlock

2 HAL_MutexDestroy

销毁一个互斥锁, 这个锁由入参标识

3 HAL_MutexLock 申请互斥锁, 如果当前该锁由其它线程持有, 则当前线程睡眠, 否则继续

4 HAL_MutexUnlock

释放互斥锁, 此后当前在该锁上睡眠的其它线程将取得锁并往下执行

5 HAL_SemaphoreCreate

创建一个信号量, 返回值可以传递给HAL_SemaphorePost/Wait

6 HAL_SemaphoreDestroy

销毁一个信号量, 这个信号量由入参标识

7 HAL_SemaphorePost

在指定的计数信号量上做自增操作, 解除其它线程的等待

8 HAL_SemaphoreWait

在指定的计数信号量上等待并做自减操作

9 HAL_ThreadCreate

根据配置参数创建thread

对以上函数接口若需了解更多细节, 可以直接访问SDK官方文档页面 .

AT MQTT相关HAL

AT MQTT相关HAL函数位于抽取出来的文件wrapper.c中, 客户需要在这些函数中调用模组提供的AT

指令和模组进行数据交互. 函数说明如下:

文档版本:20200417 303

Page 316: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

序号 函数名 说明

1 HAL_AT_MQTT_Init

初始化MQTT参数配置. 比如初始化MCU与通信模组之间的UART串口设置, 初始化MQTT配置参数: clientID/clean session/user name/password/timeout/MQTT Broker的地址和端口等数值.返回值类型为iotx_err_t, 其定义位于文件infra_defs.h

2 HAL_AT_MQTT_Deinit

如果在HAL_AT_MQTT_Init创建了一些资源, 可以在本函数中相关资源释放掉

3 HAL_AT_MQTT_Connect

连接MQTT服务器. 入参: proKey:产品密码devName:设备名devSecret:设备密码注: 只有通信模组集成了阿里的SDK的时候会使用到该函数的这几个入参, 如果模组上并没有集成阿里的SDK,那么略过这几个参数. 该函数的入参并没有指定服务器的地址/端口, 这两个参数需要在HAL_AT_MQTT_Init()中记录下来

4 HAL_AT_MQTT_Disconnect

断开MQTT服务器

5 HAL_AT_MQTT_Subscribe

向服务器订阅指定的TOPIC. 入参: topic:主题qos:服务器质量mqtt_packet_id: 数据包的IDmqtt_status: mqtt状态timeout_ms:超时时间

6 HAL_AT_MQTT_Unsubscribe

向服务器取消对指定topoic的订阅. 入参: topic:主题mqtt_packet_id:数据包的IDmqtt_status:mqtt状态

7 HAL_AT_MQTT_Publish

向服务器指定的Topic发送消息

8 HAL_AT_MQTT_State

返回MQTT的状态, 状态值定义在文件mal.h的数据结构iotx_mc_state_t中

调用接收函数

MCU从模组收到MQTT消息之后, 需要调用SDK提供的函数IOT_ATM_Input()(见atm/at_api.h)将

MQTT 消息交付给SDK。下面的示例代码演示当MCU从模组收到MQTT消息后,如何调用IOT_ATM_In

put函数:

void handle_recv_data(){ struct at_mqtt_input param; ...

param.topic = topic_ptr; param.topic_len = strlen(topic_ptr); param.message = msg_ptr; param.msg_len = strlen(msg_ptr);

if (IOT_ATM_Input(&param) != 0) { mal_err("hand data to uplayer fail!\n"); }}

304 文档版本:20200417

Page 317: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

AT Parser相关HAL

如果选择了at_parser框架, 则需要对接以下四个UART HAL函数, 函数声明见at_wrapper.h. 如果用

户不使用at_parser框架请忽略该步

序号 函数名 说明

1 HAL_AT_Uart_Init 该接口对UART进行配置(波特率/停止位等)并初始化

2 HAL_AT_Uart_Deinit

该接口对UART去初始化

3 HAL_AT_Uart_Send

该接口用于向指定的UART口发送数据

4 HAL_AT_Uart_Recv

该接口用于从底层UART buffer接收数据

产品相关HAL

下面的HAL用于获取产品的身份认证信息, 设备厂商需要设计如何在设备上烧写设备身份信息, 并通过

下面的HAL函数将其读出后提供给SDK:

序号 函数名 说明

1 HAL_GetProductKey

获取设备的ProductKey, 用于标识设备的产品型号

2 HAL_GetDeviceName

获取设备的DeviceName, 用于唯一标识单个设备

3 HAL_GetDeviceSecret

获取设备的DeviceSecret, 用于标识单个设备的密钥

对以上函数接口若需了解更多细节, 可以直接访问SDK官方文档页面

代码集成

如果设备商的开发环境使用makefile编译代码, 可以将SDK抽取出来的代码加入其编译环境进行编译.

如果设备商使用KEIL/IAR这样的开发工具, 可以将SDK抽取出来的代码文件加入到IDE的工程中进行编

参照example实现产品功能

如果要使用MQTT连云, 可参考抽取文件夹中的 eng/examples/mqtt_example_at.c . 设备厂商可以

将该文件复制到产品工程中, 对其进行修改后使用

文档版本:20200417 305

Page 318: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

该example将连接设备到阿里云, 订阅一个指定的topic并发送数据给该topic, 即设备上报的消息会被

物联网平台发送给设备, 下面是example的大概过程说明:

注意: 需要在云端将该topic从默认的权限从"订阅"修改为"发布和订阅", 如下图所示:

306 文档版本:20200417

Page 319: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

从程序入口的 main() 函数看起, 第一步是调用AT模块初始化函数IoT_ATM_Init(), 使模组处于ready

状态, 第二步是调用用户提供的HAL函数获取产品信息

int main(int argc, char *argv[]){ void * pclient = NULL; int res = 0; int loop_cnt = 0; iotx_mqtt_region_types_t region = IOTX_CLOUD_REGION_SHANGHAI; iotx_sign_mqtt_t sign_mqtt; iotx_dev_meta_info_t meta; iotx_mqtt_param_t mqtt_params;#ifdef ATM_ENABLED if (IOT_ATM_Init() < 0) { HAL_Printf("IOT ATM init failed!\n"); return -1; }#endif HAL_Printf("mqtt example\n"); memset(&meta, 0, sizeof(iotx_dev_meta_info_t)); HAL_GetProductKey(meta.product_key); HAL_GetDeviceName(meta.device_name); HAL_GetDeviceSecret(meta.device_secret);

注:

• 上面的三个HAL_GetXXX函数是获取设备的三元组信息, 设备厂商需要自己设计设备的三元组存放

的位置/并将其从指定位置读取出来

• 由于设备的唯一标识DeviceName/设备密钥DeviceSecret都是机密信息, 设备厂商在设计时可

以把相关信息加密后存放到Flash上, 在HAL函数里面将其解密后提供给SDK, 以避免黑客直接从

Flash里面读取设备的身份信息

接下来对MQTT连接参数进行指定, 客户可以根据自己的需要对参数进行修改:

/* Initialize MQTT parameter */ memset(&mqtt_params, 0x0, sizeof(mqtt_params)); mqtt_params.port = sign_mqtt.port; mqtt_params.host = sign_mqtt.hostname; mqtt_params.client_id = sign_mqtt.clientid; mqtt_params.username = sign_mqtt.username; mqtt_params.password = sign_mqtt.password;

文档版本:20200417 307

Page 320: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

mqtt_params.request_timeout_ms = 2000; mqtt_params.clean_session = 0; mqtt_params.keepalive_interval_ms = 60000; mqtt_params.read_buf_size = 1024; mqtt_params.write_buf_size = 1024; mqtt_params.handle_event.h_fp = example_event_handle; mqtt_params.handle_event.pcontext = NULL; pclient = IOT_MQTT_Construct(&mqtt_params);

通过调用接口 IOT_MQTT_Construct() 触发SDK连接云平台, 若接口返回值非NULL, 则连云成功 之后

调用example_subscribe对一个指定的topic进行数据订阅:

res = example_subscribe(pclient);

example_subscribe的函数内容如下:

注:

• 设备商需要根据自己的产品设计, 订阅自己希望订阅的TOPIC, 以及注册相应的处理函数

• 订阅的topic的格式需要指定产品型号(product_key)以及设备标识(device_name), 如上图中第一

个橙色框中的格式

• 上图的第二个框展示了如何订阅一个指定的topic以及其处理函数

以下段落演示MQTT的发布功能, 即将业务报文上报到云平台:

while (1) { if (0 == loop_cnt % 20) { example_publish(pclient);

308 文档版本:20200417

Page 321: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

IOT_MQTT_Yield(pclient, 200);

loop_cnt += 1; }

下面是example_publish函数体的部分内容:

注:

• 上面的代码是周期性的将固定的消息发送给云端, 设备商需要根据自己的产品功能, 在必要的时候

才上传数据给物联网平台

• 客户可以删除main函数中example_publish(pclient)语句, 避免周期发送无效数据给到云端

• IOT_MQTT_Yield是让SDK去接收来自MQTT Broker的数据, 其中200毫秒是等待时间, 如果用户的

消息数量比较大/或者实时性要求较高, 可以将时间改小

功能调试

下面的信息截图以mqtt_example_at.c为例编写

如何判断设备已连接到阿里云

下面的打印是HAL_Printf函数将信息打印到串口后运行example的输出内容, 其中使用橙色圈选的信

息表明设备已成功连接到阿里云物联网平台:

文档版本:20200417 309

Page 322: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如何判断设备已成功发送数据到云端

登录阿里网物联网平台的商家后台, 选中指定的设备, 可以查看是否收到来自设备的消息, 如下图所示:

注:

• 上图中的内容只能看见消息发送到了哪个topic, 消息的内容并不会显示出来

如何判断设备已可成功接收来自云端数据

在商家后台的"下行消息分析"分析中可以看见由物联网平台发送给设备的消息:

310 文档版本:20200417

Page 323: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

也可在设备端查看是否已收到来自云端的数据, exmaple代码中收到云端发送的数据的打印信息如下

所示:

至此, SDK在MCU与模组之间的适配开发已结束, 用户可以进行产品业务功能的实现

1.2.1.5.6.3 CY8C4147AZI-S475移植示例本文以cypress的CY8C4147AZI-S475芯片为例来介绍如何将SDK移植到该MCU上,并通过广域网模

组SIM800连接到阿里云物联网平台

目标

芯片 开发板 参数

CY8C4147AZI-S475 CY8CKIT-149 32bits, Cortex-M0+ 48Mhz, 128KB-Flash 16KB-SRAM

文档版本:20200417 311

Page 324: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

准备

环境搭建

• 搭建目标:MCU的两个串口(作为调试串口和与模组通信的AT串口)可以正常收发

• 开发工具: PSoC Creator 4.2,下载软件包(含CY8CKIT-149 PSoC 4100S Plus 软件包) ,下载后

解压,双击cyautorun.exe即可安装.

CY8CKIT-149

硬件连接

• 通过CY8CKIT-149的外部接口(含UART口)如下,通过TX/RX/GND连接外挂模组:

• CY8CKIT-149单板管脚说明

代码生成

PSoC Creator 4.2生成对应开发板的代码,按以下步骤完成。

• 工程创建:打开PSoC Creator,点击File -> New -> Project,依次配置以下选项,并选择Next:

- Select project type配置 -- Target Kit: CY8CKIT-149 (PSoC 4100S Plus)

- Select Project template配置 -- Code example

- Select a code example配置 -- Software_Transmit_UART该步骤完成调试串口配置,调试串

口波特为57600

• 串口配置: 添加UART选项,并按以下步骤完成配置:

- UART Component添加,将UART(SCB mode)[v4.0]拖入中间示图

- 完成UART Basic配置(双击UART图标)

- 完成UART Advanced配置

- 完成UART管脚配置

• 堆栈配置: 参考下图,完成堆、栈size配置

完成配置后,通过编译/执行Build命令,工程下会自动生成代码,代码目录如下:

SIM800

• 请根据厂商提供的应用手册自行验证SIM800通信模组是否工作正常。

本次调试使用的是开发板而非市面上常见的模组,请将SIM800C

开发板与MCU的串口(TX--RX, RX--TX, GND--GND)进行硬件

连接,注意开发板上电后按压PWRKEY按键(大于1秒),待

312 文档版本:20200417

Page 325: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

STATUS和NETLIGHT两个LED灯陆续点亮,其中NETLIGHT LED会

以2HZ进行闪烁,此时SIM800C模组ready。

SDK移植

获取代码

请到SDK下载链接下载SDK,推荐使用3.0.1版本

SDK配置与抽取

配置

• 配置命令

- Windows运行 config.bat

- Linux运行 make menuconfig

• 配置步骤 按下图进行配置,详细的配置含义请参考使能需要的SDK功能。

抽取

• 抽取命令

- Window运行extract.bat

- Linux运行extract.sh

• 抽取步骤 根据上述配置,执行抽取命令后生成的代码路径在output/eng,用户需要实现文杰

output/eng/wrappers/wrapper.c中的HAL函数。

• 抽取结果 抽取完成的SDK源码会输出到 output/eng/ 目录,结构如下:

output/eng/ ├── atm │ ├── at_api.c │ ├── at_api.h │ ├── at_conn_mbox.c │ ├── at_conn_mbox.h │ ├── at_conn_mgmt.c │ ├── at_conn_mgmt.h │ ├── at_parser.c │ ├── at_parser.h │ ├── at_tcp.c │ ├── at_wrapper.h

文档版本:20200417 313

Page 326: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

│ └── sim800.c ├── dev_sign │ ├── dev_sign_api.h │ ├── dev_sign_config.h │ ├── dev_sign_internal.h │ ├── dev_sign_mqtt.c │ └── dev_sign_wrapper.h ├── examples │ ├── dev_sign_example.c │ └── mqtt_example_at.c # 连云的mqtt示例 ├── infra │ ├── infra_compat.h │ ├── infra_config.h │ ├── infra_defs.c │ ├── infra_defs.h │ ├── infra_list.h │ ├── infra_net.c │ ├── infra_net.h │ ├── infra_report.c │ ├── infra_report.h │ ├── infra_sha256.c │ ├── infra_sha256.h │ ├── infra_string.c │ ├── infra_string.h │ ├── infra_timer.c │ ├── infra_timer.h │ └── infra_types.h ├── mqtt │ ├── iotx_mqtt_client.c │ ├── iotx_mqtt_client.h │ ├── iotx_mqtt_config.h │ ├── mqtt_api.c │ ├── mqtt_api.h │ ├── MQTTConnectClient.c │ ├── MQTTConnect.h │ ├── MQTTDeserializePublish.c │ ├── mqtt_internal.h │ ├── MQTTPacket.c │ ├── MQTTPacket.h │ ├── MQTTPublish.h │ ├── MQTTSerializePublish.c │ ├── MQTTSubscribeClient.c │ ├── MQTTSubscribe.h │ ├── MQTTUnsubscribeClient.c │ ├── MQTTUnsubscribe.h │ └── mqtt_wrapper.h └── wrappers ├── wrapper.c └── wrappers_defs.h

6 directories, 54 files

```

集成

PSoC Creator工程配置

• 抽取完成的SDK源码会输出到output/eng目录,将其中atm dev_sign infra mqtt wrappers目录

拷贝到PSoC Creator工程中新建的linkkit文件夹下,并同时,也拷贝examples下的mqtt_examp

le_at.c文件。

314 文档版本:20200417

Page 327: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 在PSoC Creator工程中添加SDK源码和头文件路径,参考流程如下:

- 新建linkkit文件夹

- 添加atm dev_sign infra mqtt wrappers目录下SDK的源文件,以及examples下的

mqtt_example_at.c文件

- 添加SDK头文件路径(同图9,右击*Project 'cy8ckit149_sim800tcp_basic',选择Build

Settings)

添加的头文件参考如下:

.\linkkit\atm; .\linkkit\dev_sign; .\linkkit\infra; .\linkkit\mqtt; .\linkkit\wrappers

代码集成

• 按上节所述,已将抽取

• 在cy8ckit149_sim800tcp_basic.cydsn/main.c中调用mqtt_example_at.c的mqtt_example函

数进行示例验证,更多其他细节请MCU+TCP模组

/* cy8ckit149_sim800tcp_basic.cydsn/main.c */

volatile uint64_t msCount = 0;void SysTickISRCallback(void){ /* Counts the number of milliseconds in one second */ msCount++;}int main(){

/* Start the SW_Tx_UART Component */ SW_Tx_UART_Start();

/* Global Int Enable */ CyGlobalIntEnable;

/* Start Systick */ CySysTickStart();

/* Register Systick Callback */ CySysTickSetCallback(0, SysTickISRCallback);

/* Enter mqtt example */ mqtt_example();}

• 三元组DeviceName ProductKey DeviceSecret 需要通过创建产品(基础版)单个创建设备

• 并注意创建时需要将产品Topic类列表中的’get’权限从默认的’订阅’改成’发布和订阅’

# wrappers/wrapper.c, 14 HAL functions implementation need to be done.int32_t HAL_AT_Uart_Init(uart_dev_t *uart);int32_t HAL_AT_Uart_Deinit(uart_dev_t *uart);int32_t HAL_AT_Uart_Recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout);int32_t HAL_AT_Uart_Send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout);

文档版本:20200417 315

Page 328: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

void *HAL_Malloc(uint32_t size);void HAL_Free(void *ptr);void HAL_Printf(const char *fmt, ...);int HAL_Snprintf(char *str, const int len, const char *fmt, ...);void HAL_SleepMs(uint32_t ms);uint64_t HAL_UptimeMs(void);

int HAL_GetDeviceName(char device_name[IOTX_DEVICE_NAME_LEN]);int HAL_GetDeviceSecret(char device_secret[IOTX_DEVICE_SECRET_LEN]);int HAL_GetProductKey(char product_key[IOTX_PRODUCT_KEY_LEN]);int HAL_GetFirmwareVersion(char *version);

• 修改cy8ckit149_sim800tcp_basic.cydsn/Generated_Source/PSoC4/cyfitter.h文件中的宏

CYDEV_HEAP_SIZE和CYDEV_STACK_SIZE,可完成堆栈配置。

/* cy8ckit149_sim800tcp_basic.cydsn/Generated_Source/PSoC4/cyfitter.h */......#define CYDEV_HEAP_SIZE 0x1400......#define CYDEV_STACK_SIZE 0x0A00......

编译烧录

• 点击菜单栏里的Build,按下图操作完成编译

• 点击菜单栏里的Debug -> program,完成烧录,烧录后复位单板即可运行

1.2.1.5.6.4 STM32F103+SIM800C移植示例本示例按照MCU+TCP模组中描述的过程,将Link Kit SDK移植到STM32F103,并结合广域

网SIM800C连接到阿里云物联网平台。在示例中SIM800C模组支持TCP能力,STM32F103上集成

了SDK并使用直接基于MQTT TOPIC的方式与阿里云物联网平台实现数据收发。

用户也可参考本移植方案,将ST其他类型的芯片实现快速连接阿里云物联网平台。

芯片 开发板 参数

STM32F103RBT6 NUCLEO-F103RB 32bits, M3 72Mhz, 128KB-Flash 20KB-SRAM

SIM800C SIM800C开发板

准备

316 文档版本:20200417

Page 329: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

环境搭建

STM32F103

• 搭建目标:MCU的两个串口(作为调试串口和与模组通信的AT串口)可以正常收发

• 开发工具:ARM® Keil® 或 IAR™。

文档版本:20200417 317

Page 330: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 硬件连接:

- MCU的AT串口通过Arduino™ Uno或ST morpho接口外接模组,示意图如下(通过TX/RX/

GND连接外挂模组)

- ST开发板ST-LINK驱动

-

318 文档版本:20200417

Page 331: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

-

文档版本:20200417 319

Page 332: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 软件环境

使用ST-cubemx新建Project后,在Board Seletor选择NUCLEO-F103RB开发板后双击,并添加

合适的串口作为MCU与模组通信的AT口,如下图USART1。

• 在Configuration中选择USARTx,并将USART1(作为AT口)的interrupt置为enable,点击Apply/

Ok后点击Cubemx的"Project"选项中的"Generate Code",设置对应的选项,其中Toolchain/

IDE可以选择ARM® Keil® 或 IAR™,Heap/Satck size按需选进行配置, 点击OK后自动生成代码和

工程。

320 文档版本:20200417

Page 333: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

配置ToolChain/IDE

文档版本:20200417 321

Page 334: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:针对不一样的应用场景,需根据实际情况合理修改heap和stack的大小(如上图中圈选位

置),在我们的测试中设置**4k(0x1000)的Heap和2.5K(0xA00)**的Stack可以正常工作

• 验证

• 根据上述软件环境配置生成对应的Keil/IAR工程,增加简单的代码,自行验证串口输入输出是否

OK。

SIM800

• 请根据厂商提供的应用手册自行验证SIM800通信模组是否工作正常。

注:本次调试使用的是开发板而非市面上常见的模组,请参考

硬件连接中的示例图与MCU的串口(TX--RX, RX--TX, GND--

GND)进行硬件连接,注意开发板上电后按压PWRKEY按键(大

322 文档版本:20200417

Page 335: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

于1秒),待STATUS和NETLIGHT两个LED灯陆续点亮,其中

NETLIGHT LED会以2HZ进行闪烁,此时SIM800C模组ready。

移植SDK

配置SDK

• 配置命令

- Windows运行 config.bat

- Linux运行 make menuconfig

• 配置步骤

如下图所示:

在本示例中使能了下面的选项:

- PLATFORM_HAS_STDINT

- PLATFORM_HAS_DYNMEM

- FEATURE_MQTT_COMM_ENABLED

■ FEATURE_MQTT_DEFAULT_IMPL

■ FEATURE_MQTT_DIRECT

- FEATURE_ATM_ENABLED

■ FEATURE_AT_TCP_ENABLED

■ FEATURE_AT_PARSER_ENABLED

■ FEATURE_AT_TCP_HAL_SIM800

文档版本:20200417 323

Page 336: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:上面选择了FEATURE_AT_TCP_HAL_SIM800,因此SDK将会生成驱动模组SIM800C相关的AT指

令代码。

抽取

• 抽取命令

- Window运行extract.bat

- Linux运行extract.sh

• 抽取步骤

执行抽取命令后生成的代码路径在output/eng,需要用户实现位于文件output/eng/wrappers/

wrapper.c中的HAL对接函数。

集成

按下述步骤集成。

步骤

• 将抽取生成的output/eng代码atm dev_sign infra mqtt wrappers目录拷贝到上述已生

成的Keil/IAR开发环境中,拷贝/使用examples下的mqtt_example_at.c作为示例,并

将mqtt_example_at.c中的main函数名更改为mqtt_example以解决编译冲突问题。

• 在Src/main.c中调用mqtt_example_at.c的mqtt_example函数进行示例验证,更多其他细节请

参照MCU+TCP模组中的相关章节。

/* add mqtt example in this file Src/main.c */int main(void){ ...... ...... /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_USART2_UART_Init(); MX_USART1_UART_Init(); ....... mqtt_example(); /* add mqtt_example here*/}

324 文档版本:20200417

Page 337: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 针对不一样的应用场景,需根据实际情况合理修改heap和stack的大小,本次组合设置4k(

0x1000)的heap和2.5K(0xA00)的stack,修改方法如下:

- Keil中MDK-ARM/startup_xx.s

- IAR中EWARM/xx_flash.icf

• 用户需要实现wrapper.c中的HAL函数

- 本例中因为选择MCU上不运行OS,因此与系统相关的HAL函数实现可以参考文件wrappers\

os\nos\HAL_Nos.c中的函数实现

- 对于 HAL_GetProductKey 、HAL_GetDeviceName 、HAL_GetDeviceSecret 需要用户返回

用户自己设备的相应身份信息

- 对于HAL_AT_Uart_Init、HAL_AT_Uart_Deinit、HAL_AT_Uart_Recv、HAL_AT_Uart_Send

需要用户去进行相关串口初始化以及数据收发

- wrapper.c参考, STM32上无OS

- wrapper.c参考, STM32上运行FreeRTOS

IDE配置

Keil/IAR 中添加SDK相关的源码文件,修改头文件路径配置:

文档版本:20200417 325

Page 338: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

Keil配置

按下图依次创建新的Group并修改为linkkit,手动添加源文件(*.c)并设置正确的头文件路径如下。编

译、烧录请参考下图6。

# 设置头文件路径,请以实际路径为准;../Src/linkkit/atm;../Src/linkkit/dev_sign;../Src/linkkit/infra;../Src/linkkit/mqtt;../Src/linkkit/wrappers

图4. Keil工程下添加Group

326 文档版本:20200417

Page 339: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

图5. Keil工程下添加.c文件

图6. Keil工程下设置头文件路径

文档版本:20200417 327

Page 340: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

IAR配置

类似步骤,依次选择Project -> Add Group,输入“linkkit”,创建新的Group之后将Src\linkkit里

所有子目录下的.c文件添加进去,最后Project -> options, 添加以下依赖的头文件路径。编译、烧录

请参考下图9。

# 设置头文件路径,请以实际路径为准$PROJ_DIR$/../Src/linkkit/atm$PROJ_DIR$/../Src/linkkit/dev_sign$PROJ_DIR$/../Src/linkkit/infra$PROJ_DIR$/../Src/linkkit/mqtt$PROJ_DIR$/../Src/linkkit/wrappers

图7. IAR工程下添加.c文件

328 文档版本:20200417

Page 341: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

图8. IAR工程下设置头文件路径

文档版本:20200417 329

Page 342: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

图9. IAR工程下编译/烧录

结果

• MCU侧Log

[10:44:17.491]收←◆sim800_uart_selfadaption 283 failed rsp OK retry count 1

[10:44:17.526]收←◆signal quality is +CSQ: 31,0

330 文档版本:20200417

Page 343: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

OK

network registration is +CREG: 0,1

OK

gprs attach check +CGATT: 1

OK

[10:44:18.809]收←◆mqtt exampleMQTT init success!establish tcp connection with server(host='a1A6QHnzzrT.iot-as-mqtt.cn-shanghai.aliyuncs.com', port=[1883])

[10:44:20.000]收←◆success to establish tcp, fd=0

[10:44:21.576]收←◆mqtt connect success!devinfo reportdevinfo report topic: /sys/a1A6QHnzzrT/test_device/thing/deviceinfo/updatedevinfo report data: {"id":"0","version":"1.0","params":[{"attrKey":"SYS_LP_SDK_VERSION","attrValue":"3.0.0","domain":"SYSTEM"},{"attrKey":"SYS_SDK_LANGUAGE","attrValue":"C","domain":"SYSTEM"}],"method":"thing.deviceinfo.update"}

[10:44:22.738]收←◆cmd AT+CIPSEND=0,267 rsp retry 1 at HAL_AT_CONN_Send 858 fail

[10:44:22.820]收←◆devinfo report succeedfirmware version report start in MQTTfirmware report topic: /ota/device/inform/a1A6QHnzzrT/test_devicefirmware report data: {"id":"1","params":{"version":"app-1.0.0-20190118.1000"}}

[10:44:23.547]收←◆firmware version report finished, iotx_publish() = 2PERFORM subscribe to '/a1A6QHnzzrT/test_device/get' (msgId=3) Packet Ident : 00000003 Topic : /a1A6QHnzzrT/test_device/get QoS : 0 Packet Length : 35

[10:44:23.861]收←◆mqtt subscribe packet sent,topic = /a1A6QHnzzrT/test_device/get!

[10:44:24.442]收←◆PUBACKmsg->event_type : 9PUBACKmsg->event_type : 9PUBACKmsg->event_type : 9SUBACK Return Value : 1 Packet ID : 3 Count : 1 Granted QoS[00] : 1packet_id = 3, event_type=3msg->event_type : 3

[10:44:25.511]收←◆PUBLISH Packet Ident : 00000000 Topic Length : 28

文档版本:20200417 331

Page 344: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

Topic Name : /a1A6QHnzzrT/test_device/get Payload Len/Room : 11 / 992 Receive Buflen : 1024delivering msg ...topic be matchedMessage Arrived: Topic : /a1A6QHnzzrT/test_device/getPayload: hello,world

[10:44:46.408]收←◆PUBLISH Packet Ident : 00000000 Topic Length : 28 Topic Name : /a1A6QHnzzrT/test_device/get Payload Len/Room : 11 / 992 Receive Buflen : 1024delivering msg ...topic be matchedMessage Arrived: Topic : /a1A6QHnzzrT/test_device/getPayload: hello,world

[10:45:07.348]收←◆PUBLISH Packet Ident : 00000000 Topic Length : 28 Topic Name : /a1A6QHnzzrT/test_device/get Payload Len/Room : 11 / 992 Receive Buflen : 1024delivering msg ...topic be matchedMessage Arrived: Topic : /a1A6QHnzzrT/test_device/getPayload: hello,world

[10:45:22.414]收←◆len = MQTTSerialize_pingreq() = 2

[10:45:23.241]收←◆send MQTT ping...

[10:45:24.246]收←◆receive ping response!

[10:45:29.128]收←◆PUBLISH Packet Ident : 00000000 Topic Length : 28 Topic Name : /a1A6QHnzzrT/test_device/get Payload Len/Room : 11 / 992 Receive Buflen : 1024delivering msg ...topic be matchedMessage Arrived: Topic : /a1A6QHnzzrT/test_device/getPayload: hello,world

1.2.1.5.7 模组上集成SDK

332 文档版本:20200417

Page 345: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.7.1 在支持TCP的广域网模组上集成SDK

注:基于Link Kit SDK v3.0.1编写

Link Kit SDK是阿里云IoT提供的用于将设备连接到阿里云IoT的设备端SDK,用于完成设备认证、数

据通信等功能。将Link Kit SDK集成到通信模组中,可以带来以下好处:

• 设备厂商在MCU上无需关心如何连接阿里云IoT,只是通过调用模组提供的AT指令就可以连接阿里

云IoT,因此对MCU的资源消耗没有增加

• 阿里将在认证合作伙伴页面露出通过认证的模组型号、购买链接、开发指导等文档,引导设备商

以及服务提供商购买通过认证的通信模组连接阿里云IoT。

使用集成了SDK的模组开发设备的示意图如下所示:

设备商开发设备的流程为:

• 购买集成了阿里云Link Kit SDK的模组

• 在MCU上通过模组提供的AT指令连接阿里云,以及从阿里云IoT收发数据

• 在阿里云IoT上部署云端服务,对设备进行管理

对于模组商而言,在模组上需要完成的工作包括:

• 将Link Kit SDK正确的集成到模组上

• 提供相应的连接阿里云IoT物联网的AT指令供MCU调用

下面的文档只讲解如何将SDK的MQTT功能集成到模组上。对于模组商来说,集成SDK的功能越多,

MCU侧设备厂商的开发功能越少,因此建议模组商尽可能多的集成SDK的功能,比如OTA、物模型

等。

在阿里云物联网平台上的操作

为了验证模组上集成的SDK是否运行正确,需要将一个测试设备连接到阿里云物联网平台。用户需要

在阿里云物联网平台上创建一个产品,并创建一个该产品的设备实例以获取到设备的身份信息。

1. 点击阿里云物联网平台登录控制台,模组商需要注册一个阿里云账号,注册阿里云账号是免费的

2. 登录阿里云物联网平台的控制台之后,按照“创建产品(基础版)”描述的步骤创建一个基础版产

品。在产品页面可以获取到产品的product_key和product_secret

文档版本:20200417 333

Page 346: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

3. 参照“创建设备”描述的步骤添加一个测试设备,在设备页面可以获取到设备

的device_name和device_secret

集成SDK的开发过程

模组商在模组上集成SDK时,需要进行下面几个开发过程:

SDK配置与代码抽取

配置SDK

SDK包含的功能较多,下面讲解如何配置本场景中需要的功能。

运行配置命令

• Linux系统

进入SDK的根目录下,运行命令

make menuconfig

• Windows系统

运行SDK根目录下的config.bat

config.bat

上面的两种方式都会启动SDK的配置工具,界面如下所示:

334 文档版本:20200417

Page 347: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

使能需要的SDK功能

在功能配置界面,按下空格键可以选中或者失效某个功能,使用小键盘的上下键来在不同功能之间

切换;如果想知道每个选项的具体含义,先用方向键将高亮光条移到那个选项上,再按键盘上的“h

”按键,将出现帮助文本,说明选项是什么含义,以及打开了和关闭了意味着什么。

如果编译环境有自带标准头文件<stdint.h>,请使能选项

• PLATFORM_HAS_STDINT

如果目标系统上运行有嵌入式操作系统,请使能选项

• PLATFORM_HAS_OS

由于模组支持TCP但是不支持MQTT,因此必须使能下面三项配置:

• FEATURE_MQTT_COMM_ENABLED,使用阿里SDK提供的MQTT API与云端通信

- FEATURE_MQTT_DEFAULT_IMPL,使用阿里SDK中自带的MQTT Client实现,用户需要实现相

关的TCP连接的创建、连接、数据收发过程

- FEATURE_MQTT_DIRECT,设备端指定阿里云物联网云端站点

建议使能FEATURE_SUPPORT_TLS,让数据与物联网平台之间的数据通信是加密的。本文档中为了降

低适配工作量,未使能该选项。

其它功能均无需使能。

文档版本:20200417 335

Page 348: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

抽取选中功能的源代码

运行SDK根目录下的extract.sh(windows下运行extract.bat),客户选中的功能所对应的代码将会

被放置到文件夹output:

将SDK代码文件加入客户编译环境

客户将上一个步骤中得到的Link Kit SDK的代码文件从output目录复制到自己的工程目录中,并修改

自己的编译环境或者开发工具将这些代码文件集成到编译环境。

客户需要集成的文件包括eng目录下面的dev_sign、infra、mqtt、wrappers目录下的代码文件:

实现HAL对接函数

336 文档版本:20200417

Page 349: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

Link Kit SDK被设计为可以在不同的操作系统上运行,或者甚至在不支持操作系统的MCU上运行,因

此与系统相关的操作被定义成一些HAL函数,需要客户进行实现;另外,由于不同的通信模组上的

OS不同,所以与通信模组上TCP相关的操作也被定义成HAL函数需要客户进行实现。

所有HAL函数位于文件为output/eng/wrappers/wrapper.c中。

系统相关HAL

必须实现函数:

** ** 函数名 说明

1 HAL_Malloc 对应标准C库中的malloc(), 按入参长度开辟一片可用内存, 并返回首地址

2 HAL_Free 对应标准C库中的free(), 将入参指针所指向的内存空间释放

3 HAL_Printf 对应标准C库中的printf(), 根据入参格式字符串将字符文本显示到终端。如果用户的调试环境有更好的调试手段,该函数无需实现

4 HAL_Snprintf 类似printf, 但输出的结果不再是显示到终端, 而是存入指定的缓冲区内存

5 HAL_UptimeMs 返回一个uint64_t类型的数值,表达设备启动后到当前时间点过去的毫秒数

6 HAL_SleepMs 按照指定入参的数值, 睡眠相应的毫秒, 比如参数是10, 那么就会睡眠10毫秒

对以上函数若需了解更多细节, 可访问SDK官方文档页面

另外,在SDK加压后的目录(非代码抽取目录)wrappers/os下有HAL的参考实现,用户可以查看是

否有自己需要的OS参考实现,若未提供则用户需要自己进行实现

可选实现函数

如果模组没有运行OS,或者SDK的MQTT API并没有在多个线程中被调用,以下函数可以不用修改

wrapper.c中相关的函数实现;在有OS场景下并且MQTT API被APP在多个线程中调用,则需要用户

对接以下函数:

文档版本:20200417 337

Page 350: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

** ** 函数名 说明

1 HAL_MutexCreate 创建一个互斥锁, 返回值可以传递给HAL_MutexLock/Unlock

2 HAL_MutexDestroy 销毁一个互斥锁, 这个锁由入参标识

3 HAL_MutexLock 申请互斥锁, 如果当前该锁由其它线程持有, 则当前线程睡眠,否则继续

4 HAL_MutexUnlock 释放互斥锁, 此后当前在该锁上睡眠的其它线程将取得锁并往下执行

5 HAL_SemaphoreCreate 创建一个信号量, 返回值可以传递给HAL_SemaphorePost/Wait

6 HAL_SemaphoreDestroy 销毁一个信号量, 这个信号量由入参标识

7 HAL_SemaphorePost 在指定的计数信号量上做自增操作, 解除其它线程的等待

8 HAL_SemaphoreWait 在指定的计数信号量上等待并做自减操作

9 HAL_ThreadCreate 根据配置参数创建thread

对以上函数接口若需了解更多细节, 可以直接访问SDK官方文档页面

TCP相关HAL

MQTT基于TCP进行通信,模组商需要实现下面四个TCP HAL函数。下面是对这些函数的说明,也可

访问SDK官方文档页面了解更多说明。

函数名 说明

1 HAL_TCP_Establish 建立一个TCP连接。注意:*入参host是一个域名,需要转换为IP地址* 返回值是tcp的socket号

2 HAL_TCP_Destroy 关闭tcp连接,入参是HAL_TCP_Establish的返回值,返回值0表示成功

338 文档版本:20200417

Page 351: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

函数名 说明

3 HAL_TCP_Write 通过TCP连接发送数据。注意:* 该函数传入了一个超时时间,如果超时仍未将数据发送结束那么函数也需要返回;* 如果TCP连接已断开,需要返回一个小于0的负数

4 HAL_TCP_Read 在指定的时间内读取数据并返回,该函数的入参中指定了可接收的数据的最大长度,如果从TCP中读取到该最大长度的数据,那么可以立即返回

产品相关HAL

下面的HAL用于获取产品的身份认证信息,设备厂商需要设计如何在设备上烧写设备身份信息,并通

过下面的HAL函数将其读出后提供给SDK:

** ** 函数名 说明

1 HAL_GetProductKey 获取设备的ProductKey, 用于标识设备的产品型号

2 HAL_GetDeviceName 获取设备的DeviceName, 用于唯一标识单个设备

3 HAL_GetDeviceSecret 获取设备的DeviceSecret, 用于标识单个设备的密钥

对以上函数若需了解更多细节, 可直接访问SDK官方文档页面

注:这几个参数在实际产品开发时应该由设备厂商通过AT指令告知模组,模组商调试时可以将自己创

建的测试设备的ProductKey、DeviceName、DeviceSecret直接通过上面这几个函数返回。

参照example实现产品功能

模组商可参考output文件夹中的 eng/examples/mqtt_example.c进行功能调试, 设备厂商可以将

该文件复制到产品工程中,对其进行修改后使用。

该example将连接设备到阿里云,订阅一个指定的topic并发送数据给该topic,即设备上报的消息会

被物联网平台发送给设备,下面是example的大概过程说明:

文档版本:20200417 339

Page 352: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注意: 需要在云端将该topic从默认的权限从”订阅”修改为”发布和订阅”, 如下图所示:

340 文档版本:20200417

Page 353: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

从程序入口的 main() 函数看起, 首先是调用模组提供的HAL函数获取产品的身份信息

int main(int argc, char *argv[]){ void *pclient = NULL; int res = 0; int loop_cnt = 0; iotx_mqtt_param_t mqtt_params;

HAL_GetProductKey(DEMO_PRODUCT_KEY); HAL_GetDeviceName(DEMO_DEVICE_NAME); HAL_GetDeviceSecret(DEMO_DEVICE_SECRET);

EXAMPLE_TRACE("mqtt example");

注:

• 上面的三个HAL_GetXXX函数是获取设备的三元组信息,模组商可以在相应的HAL函数中填入测

试设备的三元组信息即可

接下来对MQTT连接参数进行指定,客户可以根据自己的需要对参数进行修改:

/* Initialize MQTT parameter */ memset(&mqtt_params, 0x0, sizeof(mqtt_params)); mqtt_params.port = sign_mqtt.port; mqtt_params.host = sign_mqtt.hostname; mqtt_params.client_id = sign_mqtt.clientid; mqtt_params.username = sign_mqtt.username; mqtt_params.password = sign_mqtt.password; mqtt_params.request_timeout_ms = 2000; mqtt_params.clean_session = 0; mqtt_params.keepalive_interval_ms = 60000; mqtt_params.read_buf_size = 1024; mqtt_params.write_buf_size = 1024; mqtt_params.handle_event.h_fp = example_event_handle; mqtt_params.handle_event.pcontext = NULL; pclient = IOT_MQTT_Construct(&mqtt_params);

通过调用接口 IOT_MQTT_Construct() 触发SDK连接云平台, 若接口返回值非NULL, 则连云成功之后

调用example_subscribe对一个指定的topic进行数据订阅:

res = example_subscribe(pclient);

example_subscribe的函数内容如下:

文档版本:20200417 341

Page 354: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:

• 设备商需要根据自己的产品设计,订阅自己希望订阅的TOPIC,以及注册相应的处理函数;

• 上面例子程序中第一个橙色圈选的代码是指定topic的格式:/$ProductKey/$DeviceName,这

个topic是在物联网平台创建一个产品时默认生成的

• 第二个橙色圈选的代码是生成topic的内容

• 上图的第三个框展示了如何订阅一个指定的topic以及当通过该topic接收到数据时的处理函数

以下段落演示MQTT的发布功能, 即将业务报文上报到云平台:

while (1) { if (0 == loop_cnt % 20) { example_publish(pclient); }

IOT_MQTT_Yield(pclient, 200);

loop_cnt += 1; }

注:

• 上面的代码是周期性的将固定的消息发送给云端,设备商需要根据自己的产品功能,在必要的时

候才上传数据给物联网平台

• 客户可以删除main函数中example_publish(pclient)语句,避免周期发送无效数据给到云端

• IOT_MQTT_Yield是让SDK去接收来自MQTT Broker的数据,其中200毫秒是等待时间,如果用户

的消息数量比较大、或者实时性要求较高,可以将时间改小

342 文档版本:20200417

Page 355: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

下面是example_publish函数体的内容:

上面图中第一个框是发送的消息的内容,第二个框是调用SDK提给的API将消息发送给指定的topic。

上传模组商编码和模组型号

如果模组商希望将模组送到阿里云IoT进行模组认证,那么模组商需要将模组商编码和模组型号进行

上报,这样阿里云物联网平台可以统计通过指定模组商连接到平台的设备数量,也可以统计通过模组

商的某个型号模组连接设备的数量。

模组商编码和模组型号请在集成SDK前联系阿里进行获取,请将邮件发送到邮箱

[email protected],并在主题中标注“模组/芯片型号申请”。注:非模组商

无需申请编__码。

当模组与阿里云物联网平台建立连接之后,请复制并调用下面的函数进行信息上报,其中参数pid是

模组商编码、mid是型号编码:

#define PID_STRING_LEN_MAX 32 /* PID字符串最大长度 */#define MID_STRING_LEN_MAX 32 /* MID字符串最大长度 */

int example_report_pid_mid(void *pclient, const char *product_key, const char *device_name, const char *pid, const char *mid){ int res = 0; iotx_mqtt_topic_info_t topic_msg;

const char topic_frag1[] = "/sys/"; const char topic_frag2[] = "/thing/deviceinfo/update";

文档版本:20200417 343

Page 356: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

char topic[sizeof(topic_frag1) + sizeof(topic_frag2) + IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN] = {0};

const char payload_frag1[] = "{\"id\":\"0\",\"version\":\"1.0\",\"params\":[{\"attrKey\":\"SYS_MODULE_ID\",\"attrValue\":\""; const char payload_frag2[] = "\",\"domain\":\"SYSTEM\"},{\"attrKey\":\"SYS_PARTNER_ID\",\"attrValue\":\""; const char payload_frag3[] = "\",\"domain\":\"SYSTEM\"}],\"method\": \"thing.deviceinfo.update\"}"; char payload[sizeof(payload_frag1) + sizeof(payload_frag2) + sizeof(payload_frag3) + PID_STRING_LEN_MAX + MID_STRING_LEN_MAX] = {0};

if (strlen(pid) > PID_STRING_LEN_MAX || strlen(mid) > MID_STRING_LEN_MAX) { return -1; }

/* 组装MQTT topic字符串 */ memcpy(topic, topic_frag1, strlen(topic_frag1)); memcpy(topic + strlen(topic), product_key, strlen(product_key)); memcpy(topic + strlen(topic), "/", 1); memcpy(topic + strlen(topic), device_name, strlen(device_name)); memcpy(topic + strlen(topic), topic_frag2, strlen(topic_frag2));

/* 组装MQTT payload字符串, payload中包含了PID, MID字符串 */ memcpy(payload, payload_frag1, strlen(payload_frag1)); memcpy(payload + strlen(payload), mid, strlen(mid)); memcpy(payload + strlen(payload), payload_frag2, strlen(payload_frag2)); memcpy(payload + strlen(payload), pid, strlen(pid)); memcpy(payload + strlen(payload), payload_frag3, strlen(payload_frag3));

topic_msg.qos = IOTX_MQTT_QOS0; topic_msg.retain = 0; topic_msg.dup = 0; topic_msg.payload = (void *)payload; topic_msg.payload_len = strlen(payload);

/* 使用MQTT publish API发送PID,MID信息报文 */ res = IOT_MQTT_Publish(pclient, topic, &topic_msg); if (res < 0) { return -1; }

return 0;}

功能调试

下面的信息截图以mqtt_example.c为例编写。

如何判断设备已连接到阿里云

注意:/${productKey}/${deviceName}/get这个topic默认只有“订阅”权限,请在物联网平台的

控制台将其修改为“发布和订阅”,避免消息发送到云端后被云端丢弃; 把该topic修改为“发布和

订阅”,主要是为了让example程序运行不出错。

344 文档版本:20200417

Page 357: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

下面的打印是HAL_Printf函数将信息打印到串口后运行example的输出内容,其中使用橙色圈选的信

息表明设备已成功连接到阿里云物联网平台:

如何判断设备已成功发送数据到云端

登录阿里网物联网平台的商家后台,选中指定的设备,可以查看是否收到来自设备的消息,如下图所

示:

注:上图中的内容只能看见消息发送到了哪个topic,消息的内容并不会显示出来

如何判断设备已可成功接收来自云端数据

在商家后台的“下行消息分析”分析中可以看见由物联网平台发送给设备的消息:

文档版本:20200417 345

Page 358: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

也可在设备端查看是否已收到来自云端的数据,exmaple代码中收到云端发送的数据的打印信息如下

所示:

AT指令实现

如果模组不提供开发环境给用户进行二次开发,而是外接一个MCU并且产品的业务逻辑运行在MCU

上,那么模组商还需要提供AT指令给MCU调用,由于模组以前只支持TCP,所以需要提供MQTT连接

配置、发起连接、断开连接、订阅、Publish等接口。

下面是推荐增加的AT指令(模组商也可以合并这些指令或者拆分指令),格式由模组商自行定义:

346 文档版本:20200417

Page 359: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

指令项 说明

阿里设备身份信息设置 设置设备的product_key, product_secret, device_name, device_secret

阿里云端region设置 阿里云IoT提供中国、美国、日本等多个云端站点,可以让MCU指定需要连接的阿里云IoT的站点以及端口信息

建立MQTT连接 建立到阿里云MQTT Broker的连接,该指令中可以指定MQTT clean session、keepalive间隔、Req Timeout时间

断开MQTT连接 断开与阿里云IoT的MQTT连接

订阅某个Topic 对某个Topic进行消息订阅

取消Topic订阅 取消对某个topic的消息订阅

向某个topic发送数据 向指定的topic发送数据

注:当MCU通过AT指令将设备身份信息传递到模组时,建议将设备身份信息存储到全局变量中,并

在HAL_GetProductKey、HAL_GetDeviceName、HAL_GetDeviceSecret等几个HAL函数中将其进

行返回,这样example程序不用进行修改。

总结

本文描述了在模组上集成SDK的MQTT功能,并与阿里云物联网平台进行通信的过程。模组商可以集

成更多的SDK功能,请参见官网编程文档决定是否集成其它功能,比如物模型、OTA、设备影子等

等。

1.2.1.5.7.2 在支持MQTT的模组上集成SDK

本文讲解模组商在支持MQTT的通信模组上如何集成阿里云IoT提

供的Link Kit SDK,以及完成相关需要完成的工作。本文档基于

Link Kit SDK 3.0.1进行编写。

场景说明

Link Kit SDK是阿里云IoT提供的用于将设备连接到阿里云IoT的设备端SDK,用于完成设备认证、数

据通信等功能。将Link Kit SDK集成到通信模组中,可以带来以下好处:

• 设备厂商在MCU上无需关心如何连接阿里云IoT,只是通过调用模组提供的AT指令就可以连接阿里

云IoT,因此对MCU的资源消耗没有增加

• 阿里将在认证合作伙伴页面露出通过认证的模组型号、购买链接、开发指导等文档,引导设备商

以及服务提供商购买通过认证的通信模组连接阿里云IoT。

文档版本:20200417 347

Page 360: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

使用集成了SDK的模组开发设备的示意图如下所示:

设备商开发设备的流程为:

• 购买集成了阿里云Link Kit SDK的模组

• 在MCU上通过模组提供的AT指令连接阿里云,以及从阿里云IoT收发数据

• 在阿里云IoT上部署云端服务,对设备进行管理

对于模组商而言,在模组上需要完成的工作包括:

• 将Link Kit SDK正确的集成到模组上

• 提供相应的连接阿里云IoT物联网的AT指令供MCU调用

文档目标

本文讲解如何将Link Kit SDK集成到已支持MQTT协议的模组上,让模组商了解集成SDK的大概过程。

为了简化难度,本文只讲解如何集成Link Kit SDK的设备签名模块,从而让模组可以接入到阿里云物

联网平台。

建议模组商尽量多的集成Link Kit SDK的功能,比如物模型、

OTA、设备影子等功能,因为模组上集成的Link Kit SDK的功能

越多,意味着设备商连接阿里云物联网平台时可以使用的功能越

多。

由于模组已支持MQTT协议,SDK将会利用模组上已具备的MQTT功能模块,Link Kit SDK提供API生

成连接阿里云物联网平台MQTT Broker所需要的ClientID、UserName、Password等信息,然后模

组商使用这些数据与阿里云物联网平台的Broker建立连接,并继而实现对MQTT Topic的订阅或者向

指定Topic发送数据。

在阿里云物联网平台创建基础版产品

模组商在调试的时候,需要创建一个测试产品和一个测试设备,用于验证SDK是否已正常工作。请按

照下面的过程创建设备:

1. 点击阿里云物联网平台登录控制台,模组商需要注册一个阿里云账号,注册阿里云账号是免费的

348 文档版本:20200417

Page 361: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. 登录阿里云物联网平台的控制台之后,按照“创建产品(基础版)”描述的步骤创建一个基础版产

品。在产品页面可以获取到产品的product_key和product_secret

3. 参照“单个创建设备”描述的步骤添加一个测试设备,在设备页面可以获取到设备

的device_name和device_secret

下面讲解模组商在模组上集成SDK的开发过程:

集成SDK的开发过程

模组商集成SDK时,需要进行下面几个开发过程:

SDK配置与代码抽取

SDK包含的功能较多,为了避免SDK消耗过多的RAM和Flash,SDK提供配置和抽取工具让开发者只

使用需要的组件。

配置SDK

下面讲解模组商如何配置需要的软件功能。

运行配置命令

• Linux系统

进入SDK的根目录下,运行命令

make menuconfig

• Windows系统

运行SDK根目录下的config.bat

config.bat

上面的两种方式都会启动SDK的配置工具,界面如下所示:

文档版本:20200417 349

Page 362: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:

• 功能配置选项前的号表示该功能被使能,没有号表示该功能未被使能

• 表格中显示的是可配置的选项,因此即使将所有选项都失效,SDK中不能失效的功能仍然有效

• 按下空格键可以选中或者失效某个功能,使用小键盘的上下键来在不同功能之间切换;

• 如果想知道每个选项的具体含义,先用方向键将高亮光条移到那个选项上,再按键盘上的“h”按

键,将出现帮助文本,说明选项是什么含义,打开了和关闭了意味着什么。

对于本场景而言:

• 如果开发环境支持<stdint.h>,那么使能PLATFORM_HAS_STDINT

• 如果开发环境支持malloc/free,那么使能PLATFORM_HAS_DYNMEM

• 如果运行环境有OS,那么使能PLATFORM_HAS_OS

其它选项均不使能。配置完成之后,通过“Exit”按键退出,并根据提示保存配置。

抽取SDK代码

下面讲解如何抽取SDK代码

运行抽取命令

• Linux系统

进入SDK的根目录下,运行命令

sh ./extract.sh

• Windows系统

350 文档版本:20200417

Page 363: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

运行SDK根目录下的config.bat

extract.bat

上面的两种方式都会启动SDK的代码抽取工具,抽取工具将会把必要的文件抽取之后放置到output目

录下,如下所示:

SDK文件加入用户工程

用户可以将output目录下的eng文件夹复制到自己的工程目录,然后将代码文件添加到工程中。

需要添加的文件位于目录eng/dev_sign,eng/infra,eng/wrappers中,编译的时候也需要指定头

文件查找路径包含这几个目录

HAL对接

将Link Kit SDK与已有MQTT融合

生成MQTT ClientID、UserName、Password

MQTT Client连接MQTT Broker时需要指定ClientID、UserName、Password等信息,Link Kit SDK

提供API IOT_Sign_MQTT()用于生成这些数据:

int32_t IOT_Sign_MQTT(iotx_mqtt_region_types_t region, iotx_dev_meta_info_t *meta, iotx_sign_mqtt_t *signout)

注:使用该函数需要包含头文件dev_sign_internal.h:

#include "dev_sign_internal.h"

文档版本:20200417 351

Page 364: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

入参说明:

• region

指定连接的阿里云IoT的云端站点,可选值定义在文件eng/infra/infra_defs.h中:

typedef enum { IOTX_CLOUD_REGION_SHANGHAI, /* Shanghai */ IOTX_CLOUD_REGION_SINGAPORE, /* Singapore */ IOTX_CLOUD_REGION_JAPAN, /* Japan */ IOTX_CLOUD_REGION_USA_WEST, /* America */ IOTX_CLOUD_REGION_GERMANY, /* Germany */ IOTX_CLOUD_REGION_CUSTOM, /* Custom setting */ IOTX_CLOUD_DOMAIN_MAX /* Maximum number of domain */} iotx_mqtt_region_types_t;

• 如果模组在国内售卖,将该参数设置为IOTX_CLOUD_REGION_SHANGHAI

• meta

指定设备的身份信息,数据结构定义如下:

typedef struct { char product_key[IOTX_PRODUCT_KEY_LEN + 1]; char product_secret[IOTX_PRODUCT_SECRET_LEN + 1]; char device_name[IOTX_DEVICE_NAME_LEN + 1]; char device_secret[IOTX_DEVICE_SECRET_LEN + 1];} iotx_dev_meta_info_t;

其中的四个变量是产品在阿里云物联网平台定义完毕之后,由设备商为每个设备申请的;在实际产品

开发时,这几个参数需要由MCU通过AT指令传递给模组

出参说明

• signout

该参数输出连接MQTT Broker时需要的ClientID、Username、Password等信息,结构定义如下:

typedef struct { char hostname[DEV_SIGN_HOSTNAME_MAXLEN]; uint16_t port; char clientid[DEV_SIGN_CLIENT_ID_MAXLEN]; char username[DEV_SIGN_USERNAME_MAXLEN]; char password[DEV_SIGN_PASSWORD_MAXLEN];} iotx_sign_mqtt_t;

其中hostname是阿里云物联网云端站点MQTT Broker的域名,port是阿里云物联网云端站点的

MQTT Broker的端口号。

352 文档版本:20200417

Page 365: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

成功该函数将返回0,错误将返回-1。

使用示例

eng\examples\dev_sign_example.c中示范了如何使用IOT_Sign_MQTT()函数,下面是代码片段

示例:

#define EXAMPLE_PRODUCT_KEY "a1X2bEnP82z"#define EXAMPLE_PRODUCT_SECRET "7jluWm1zql7bt8qK"#define EXAMPLE_DEVICE_NAME "example1"#define EXAMPLE_DEVICE_SECRET "ga7XA6KdlEeiPXQPpRbAjOZXwG8ydgSe"

/* Implenment this HAL or using "printf" of your own system if you want to print something in example*/void HAL_Printf(const char *fmt, ...);

int main(int argc, char *argv[]){ iotx_mqtt_region_types_t region = IOTX_CLOUD_REGION_SHANGHAI; iotx_dev_meta_info_t meta; iotx_sign_mqtt_t sign_mqtt;

memset(&meta,0,sizeof(iotx_dev_meta_info_t)); memcpy(meta.product_key,EXAMPLE_PRODUCT_KEY,strlen(EXAMPLE_PRODUCT_KEY)); memcpy(meta.product_secret,EXAMPLE_PRODUCT_SECRET,strlen(EXAMPLE_PRODUCT_SECRET)); memcpy(meta.device_name,EXAMPLE_DEVICE_NAME,strlen(EXAMPLE_DEVICE_NAME)); memcpy(meta.device_secret,EXAMPLE_DEVICE_SECRET,strlen(EXAMPLE_DEVICE_SECRET));

if (IOT_Sign_MQTT(region,&meta,&sign_mqtt) < 0) { return -1; } ...}

在该示例中,设备的product_key、product_secret、device_name、device_secret都使用了固定

的数值,在实际产品运行时需要由MCU告知模组。

在模组商调试时,模组商需要自己到阿里云物联网平台去创建产品和测试设备,然后使用平台为设备

生成的product_key、product_secret、device_name、device_secret。

上传模组商编码和模组型号

如果模组商希望将模组送到阿里云IoT进行模组认证,那么模组商需要将模组商编码和模组型号进行

上报,这样阿里云物联网平台可以统计通过指定模组商连接到平台的设备数量,也可以统计通过模组

商的某个型号模组连接设备的数量。

文档版本:20200417 353

Page 366: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

模组商编码和模组型号请在集成SDK前联系阿里进行获取,请将邮件发送到邮箱

[email protected],并在主题中标注“模组/芯片型号申请”。注:非模组商

无需申请编__码。

当模组与阿里云物联网平台建立连接之后,请复制并调用下面的函数进行信息上报,其中参数pid是

模组商编码、mid是型号编码:

#define PID_STRING_LEN_MAX 32 /* PID字符串最大长度 */#define MID_STRING_LEN_MAX 32 /* MID字符串最大长度 */

int example_report_pid_mid(void *pclient, const char *product_key, const char *device_name, const char *pid, const char *mid){ int res = 0; iotx_mqtt_topic_info_t topic_msg;

const char topic_frag1[] = "/sys/"; const char topic_frag2[] = "/thing/deviceinfo/update"; char topic[sizeof(topic_frag1) + sizeof(topic_frag2) + IOTX_PRODUCT_KEY_LEN + IOTX_DEVICE_NAME_LEN] = {0};

const char payload_frag1[] = "{\"id\":\"0\",\"version\":\"1.0\",\"params\":[{\"attrKey\":\"SYS_MODULE_ID\",\"attrValue\":\""; const char payload_frag2[] = "\",\"domain\":\"SYSTEM\"},{\"attrKey\":\"SYS_PARTNER_ID\",\"attrValue\":\""; const char payload_frag3[] = "\",\"domain\":\"SYSTEM\"}],\"method\": \"thing.deviceinfo.update\"}"; char payload[sizeof(payload_frag1) + sizeof(payload_frag2) + sizeof(payload_frag3) + PID_STRING_LEN_MAX + MID_STRING_LEN_MAX] = {0};

if (strlen(pid) > PID_STRING_LEN_MAX || strlen(mid) > MID_STRING_LEN_MAX) { return -1; }

/* 组装MQTT topic字符串 */ memcpy(topic, topic_frag1, strlen(topic_frag1)); memcpy(topic + strlen(topic), product_key, strlen(product_key)); memcpy(topic + strlen(topic), "/", 1); memcpy(topic + strlen(topic), device_name, strlen(device_name)); memcpy(topic + strlen(topic), topic_frag2, strlen(topic_frag2));

/* 组装MQTT payload字符串, payload中包含了PID, MID字符串 */ memcpy(payload, payload_frag1, strlen(payload_frag1)); memcpy(payload + strlen(payload), mid, strlen(mid)); memcpy(payload + strlen(payload), payload_frag2, strlen(payload_frag2)); memcpy(payload + strlen(payload), pid, strlen(pid)); memcpy(payload + strlen(payload), payload_frag3, strlen(payload_frag3));

topic_msg.qos = IOTX_MQTT_QOS0; topic_msg.retain = 0; topic_msg.dup = 0; topic_msg.payload = (void *)payload; topic_msg.payload_len = strlen(payload);

/* 使用MQTT publish API发送PID,MID信息报文, 由于使用模组上自带的MQTT功能, 模组商集成时需要将下面的publish函数换为实际的publish函数*/ res = IOT_MQTT_Publish(pclient, topic, &topic_msg); if (res < 0) { return -1;

354 文档版本:20200417

Page 367: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

return 0;}

调试

将模组连接到阿里云物联网平台

模组商需要编写函数用于将模组连接到阿里云物联网平台,模组上的MQTT应该会提供一个连接

MQTT Broker的函数,在其中需要输入通过调用Link Kit SDK提供的API IOT_Sign_MQTT()获取到的

域名、端口、ClientID、usename、password等信息。

下面是将SDK与一个mosquitto集成(一个开源的MQTT库)的示例伪代码:

//调用签名函数获取MQTT username、password、clientID等信息 IOT_Sign_MQTT(region,&meta,&sign_mqtt);

mosquitto_lib_init();

//下面的代码设置了mqtt clientID和cleansession参数 mosq = mosquitto_new(sign_mqtt.clientid,0/*dont clean session*/,NULL); if(mosq==NULL){ printf("Error:Failed creating mosquitto client\n\r"); return(-1); } //下面的代码设置了MQTT连接时使用的username和password if(0 != mosquitto_username_pw_set(mosq, sign_mqtt.username, sign_mqtt.password)){ printf("Error:Failed setting username or password\n\r"); return(-1); }

... //下面的代码用于建立到MQTT Broker的连接,其中使用到了域名、端口 if(mosquitto_connect(mosq, sign_mqtt.hostname, sign_mqtt.port, kaInterval)){ printf("Error: Failed connecting cloud.\n\r"); sleep(1); return -1; }

注:MQTT建立连接时还需要指定keepalive间隔,该值的推荐值为60秒,模组商也可以将该参数的

设置提供AT指令给MCU进行动态修改,阿里云物联网平台接受的keepalive间隔范围为30~1200

秒。

模组正常连接到物联网平台之后,如果模组没有断开MQTT连接,模组将处于在线状态。可以在阿里

云物联网平台的控制台找到测试设备,查看其状态(下图展示了一个在线设备的状态):

文档版本:20200417 355

Page 368: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如何判断程序可正常发送数据到物联网平台

当模组与阿里云物联网平台已建立连接之后,可以向topic /${productKey}/${deviceName}/get发

送一个消息,来检查数据是否已可以正常发送到物联网平台。

注意:/${productKey}/${deviceName}/get这个topic默认只有“订阅”权限,请在物联网平台的

控制台将其修改为“发布和订阅”,避免消息发送到云端后被云端丢弃; 把该topic修改为“发布和

订阅”,主要是为了让example程序运行不出错。

下面是一个参考实现示例:

int res = 0; iotx_mqtt_topic_info_t topic_msg; const char *fmt = "/%s/%s/get"; char *topic = NULL; int topic_len = 0; char *payload = "hello,world";

topic_len = strlen(fmt) + strlen(product_key) + strlen(device_name) + 1; topic = HAL_Malloc(topic_len); if (topic == NULL) { HAL_Printf("memory not enough\n"); return -1; } memset(topic, 0, topic_len); //此处生成topic HAL_Snprintf(topic, topic_len, fmt, product_key, device_name);

//下面的代码生成一个消息 memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t)); topic_msg.qos = IOTX_MQTT_QOS0; topic_msg.retain = 0; topic_msg.dup = 0; topic_msg.payload = (void *)payload; topic_msg.payload_len = strlen(payload);

//下面的代码向指定的topic发送消息,请使用模组上的MQTT Publish函数替换下面的发送函数 res = IOT_MQTT_Publish(handle, topic, &topic_msg);

在物联网平台的控制台上,在具体的设备的日志服务中,可以查看物联网平台是否已接收到该数据:

356 文档版本:20200417

Page 369: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:

• 日志会显示在什么时间收到了来自设备的消息,也会显示收到消息的topic,并不会显示消息的内

• 阿里云物联网平台目前不支持QoS2

如何判断程序已正确订阅TOPIC

模组商可以向topic /{productKey}/${deviceName}/get订阅数据,这样当设备上报一个数据到物联

网平台后,平台又会将数据发送回设备,从而让模组商得知订阅是否工作正常。下面是示例伪代码:

int res = 0; const char *fmt = "/%s/%s/get"; char *topic = NULL; int topic_len = 0;

topic_len = strlen(fmt) + strlen(product_key) + strlen(device_name) + 1; topic = HAL_Malloc(topic_len); if (topic == NULL) { HAL_Printf("memory not enough\n"); return -1; } //下面的代码用于组装topic memset(topic, 0, topic_len); snprintf(topic, topic_len, fmt, product_key, device_name);

/*下面的代码用于订阅topic,以及指定消息处理函数。 请使用模组上实际的MQTT subscribe函数替换下面的代码*/ res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL);

在物联网平台的控制台,模组商可以查看平台是否将数据发送给了设备:

文档版本:20200417 357

Page 370: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:

• 日志会显示在什么时间发送了消息到设备端,不会显示消息内容

• 模组商需要在模组上查看收到的数据是否是自己上传的数据,来确保接收数据工作正常

AT指令实现

模组商还需要提供AT指令给MCU调用,由于模组以前已支持MQTT,所以应该已经提供MQTT连接配

置、发起连接、断开连接、订阅、Publish等接口。集成了Link Kit SDK之后,模组商可以新增针对阿

里云的AT指令,也可以修改目前已有的AT指令。

下面是推荐增加的AT指令:

指令项 说明

阿里设备身份信息设置 设置设备的product_key, product_secret, device_name, device_secret

阿里云端region设置 阿里云IoT提供中国、美国、日本等多个云端站点,可以让MCU指定需要连接的阿里云IoT的站点以及端口信息

其余的MQTT指令可以继续使用模组商已有的指令

358 文档版本:20200417

Page 371: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.7.3 庆科MK3060/MK3080AliOS Things已经支持了庆科的WiFi模组MK3060和3080, 实现了Link Kit SDK需要的HAL函数,因

此SDK如果要运行在这两款集成了AliOS Things的模组上,可以参考下面的说明生成适用的SDK。

__选择平台配置 __

make reconfigSELECT A CONFIGURATION:

1) config.esp8266.aos 4) config.mk3080.aos 7) config.win7.mingw322) config.macos.make 5) config.rhino.make3) config.mk3060.aos 6) config.ubuntu.x86#? 3

__*如果是为庆科MK3080编译, 则选择4* __

编译

make

如果您当前的开发主机上没有安装庆科 MK3060/MK3080 的交叉工具链并导出到 PATH 中, C-SDK会

自动下载它们

make

BUILDING WITH EXISTING CONFIGURATION:

VENDOR : mk3060MODEL : aos

https://gitee.com/alios-things/gcc-arm-none-eabi-linux -> .O/compiler/gcc-arm-none-eabi-linux/main---downloading toolchain for arm-none-eabi-gcc .................... [\]

下载完成后, 自动开始交叉编译SDK的源码

https://gitee.com/alios-things/gcc-arm-none-eabi-linux -> .O/compiler/gcc-arm-none-eabi-linux/main---downloading toolchain for arm-none-eabi-gcc .................... done

[CC] utils\_epoch\_time.o <= ...[CC] json\_parser.o <= .........[AR] libiot\_sdk.a <= ...

获取二进制库

cd output/release/libls

文档版本:20200417 359

Page 372: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中有一个主要产物, **它是 MK3060/MK3080 架构的**:

产物文件名 说明

libiot\_sdk.a SDK的主库, 提供了 IOT\_XXX 接口和 linkkit\_xxx() 接口

1.2.1.5.7.4 乐鑫ESP8266AliOS Things已经支持了乐鑫ESP8266 WiFi模组, 实现了Link Kit SDK需要的HAL函数,因此

SDK如果要运行在集成了AliOS Things的乐鑫ESP8266 WiFi模组,可以参考下面的说明生成适用

于ESP8266的型号的SDK。

make reconfig

SELECT A CONFIGURATION:

1) config.alios.esp82662) config.alios.mk30803) config.ubuntu.x86#? 1

编译

make

如果您当前的开发主机上没有安装乐鑫 ESP8266 的交叉工具链并导出到 PATH 中, C-SDK会自动下载

它们

make

BUILDING WITH EXISTING CONFIGURATION:

VENDOR : aliosMODEL : esp8266

https://gitee.com/alios-things/gcc-xtensa-lx106-linux -> .O/compiler/gcc-xtensa-lx106-linux/main---downloading toolchain for xtensa-lx106-elf-gcc .................... [/]

下载完成后, 自动开始交叉编译SDK的源码

https://gitee.com/alios-things/gcc-arm-none-eabi-linux -> .O/compiler/gcc-arm-none-eabi-linux/main---downloading toolchain for xtensa-lx106-elf-gcc .................... done

[CC] infra_preauth.o <= ...[CC] infra_timer.o <= ...[CC] infra_json_parser.o <= ...

360 文档版本:20200417

Page 373: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

...

...[AR] libiot_sdk.a <= ...

获取二进制库

cd output/release/libls

其中有一个主要产物, 它是 ESP8266 架构的:

产物文件名 说明

libiot_sdk.a SDK的主库, 提供了 IOT_XXX 接口

1.2.1.5.7.5 MTK2503/MTK6261 + Nucleus 移植示例移植说明:本文档描述在MTK2503/MTK6261芯片 + Nucleus操作系统的硬件平台上,使用异步通信

模式将SDK集成到目标平台,集成时使用MQTT Topic方式与阿里云物联网平台进行通信。

开发环境: Windows XP开发主机及MTK的USB转串口驱动, ARM RVCT3.1/Perl构建环境, FlashTool

烧录工具, Catcher调试工具

运行顶级目录下的 config.bat 脚本, 在出现的界面关闭 FEATURE_DEVICE_MODEL_ENABLED, 然后

进入 MQTT Configuations 子菜单

前面已经介绍过, FEATURE_ASYNC_PROTOCOL_STACK 是专为异步TCP/IP协议栈开发的特性, 所以

这里选中它, 打开

文档版本:20200417 361

Page 374: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

保存后退出, 运行顶级目录下的 extract.bat 脚本, 根据这种配置抽取移植所需要的源文件到 output

目录下

对接HAL接口

上图中可以看到 extract.bat 已经将需要对接的HAL接口列出并自动整理到 output/eng/wrappers/

wrapper.c, 用户现在要根据系统的情况将这个文件中的空函数都进行实现

可以直接使用SDK源码目录 wrappers/os/nucleus 中的参考代码, 根据自己的实际需要做一些调整

362 文档版本:20200417

Page 375: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

将被抽取的文件和实现好的 wrapper.c 加入构建

拷贝 output/eng 下所有目录及文件到 Nucleus 的编译环境中, 确保编译通过, 可以将C-SDK作为一

个库集成到原有系统中

参考如下源码编写应用调用C-SDK

以下是我们开发过程中经过实际验证的源文件, 您可参考编写自己的应用程序调用被集成的C-SDK

• aliMqttSap.h

• aliMqttTask.h

• aliMqttTask.c

例程讲解

以下对示例的 aliMqttTask.c 运行流程做一些讲解

监听系统事件, 构造应用程序入口

监听 Nucleus 中系统事件 EVT_ID_SRV_NW_INFO_SERVICE_AVAILABILITY_CHANGED, 当GPRS连

接成功, 系统会触发该事件

/* 系统事件回调函数 */mmi_ret srv_nw_name_main_evt_hdlr(mmi_event_struct *event){ ...switch (event->evt_id) ... case EVT_ID_SRV_NW_INFO_SERVICE_AVAILABILITY_CHANGED: ret = srv_nw_name_handle_service_availability_changed(event); ...

把事件传递给状态机处理函数: aliyun_network_changed()

static mmi_ret srv_nw_name_handle_service_availability_changed(mmi_event_struct *event){ ... #if defined(__LL_ALIYUN_SUPPORT__) /* 进入业务回调函数,处理系统事件 */ aliyun_network_changed((kal_int32)evt->new_status); #endif /*__LL_MYCOMMON_SUPPORT__*/ ...}

文档版本:20200417 363

Page 376: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如果 aliyun_network_changed() 发现事件是表达 GPRS 连接已就绪, 则启动应用程序 ali_app_st

art_fun()

#define ALIYUN_NETWORK_GPRS_OK 3void aliyun_network_changed(kal_int8 status){ ... /* srv_nw_info_location_info_struct info; */ DEBUG_TRACE("service_changedstatus.status=%d",status);

g_gprs_status = status; /* 该事件表示GPRS连接成功 */ if (g_gprs_status == ALIYUN_NETWORK_GPRS_OK) { if(g_sim_init_complete == KAL_FALSE) { g_sim_init_complete = KAL_TRUE; StopTimer(ALIYUN_START_TIMER); /* 这里开始执行业务逻辑 */ StartTimer(ALIYUN_START_TIMER,1000*20,ali_app_start_fun);

} } ...}

同时, 我们也构造了一个专用于MQTT通信的任务: mqtt_task_main()

kal_bool mqtt_create(comptask_handler_struct **handle){ static const comptask_handler_struct mqtt_handler_info = { mqtt_task_main, /* task entry function */ mqtt_task_init, /* task initialization function */ NULL, /* task configuration function */ NULL, /* task reset handler */ NULL, /* task termination handler */ };

*handle = (comptask_handler_struct*)&mqtt_handler_info;

return KAL_TRUE;}

GPRS连接成功, 计算签名信息, 并解析签名中的服务器域名为IP

ali_app_start_fun() 首先会调用SDK提供的接口 IOT_MQTT_Sign() 获取签名信息, 其中含有服务器

域名

static void ali_app_start_fun(void){ uint32_t res = 0; iotx_dev_meta_info_t meta; ...

364 文档版本:20200417

Page 377: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

res = IOT_Sign_MQTT(IOTX_CLOUD_REGION_SHANGHAI,&meta,&g_mqtt_signout); if (res == 0) { DEBUG_TRACE("signout.hostname: %s",g_mqtt_signout.hostname); DEBUG_TRACE("signout.port : %d",g_mqtt_signout.port); DEBUG_TRACE("signout.clientid: %s",g_mqtt_signout.clientid); DEBUG_TRACE("signout.username: %s",g_mqtt_signout.username); DEBUG_TRACE("signout.password: %s",g_mqtt_signout.password);

用 Nucleus 的系统接口 soc_gethostbyname() 把域名解析成IP地址

... ... res = soc_gethostbyname(KAL_FALSE,MOD_MQTT,g_ali_request_id,g_mqtt_signout.hostname, (kal_uint8 *)addr_buff, &addr_len,0,g_ali_nwk_account_id);

若域名成功解析, 则调用SDK提供的接口 IOT_MQTT_Construct() 发起TCP连接

if (res >= SOC_SUCCESS) // success { DEBUG_TRACE("ali task socket_host_by_name SOC_SUCCESS"); if(addr_len !=0 && addr_len<MAX_SOCK_ADDR_LEN) { //connect.... sprintf(ipaddr,"%d.%d.%d.%d",addr_buff[0],addr_buff[1],addr_buff[2],addr_buff[3]); DEBUG_TRACE("ipaddr: %s[%d.%d.%d.%d]",ipaddr,addr_buff[0],addr_buff[1],addr_buff[2],addr_buff[3]); HAL_Free(g_mqtt_signout.hostname); g_mqtt_signout.hostname = HAL_Malloc(strlen(ipaddr) + 1); if (g_mqtt_signout.hostname == NULL) { DEBUG_TRACE("HAL_Malloc failed"); return; } memset(g_mqtt_signout.hostname,0,strlen(ipaddr) + 1); memcpy(g_mqtt_signout.hostname,ipaddr,strlen(ipaddr));

DEBUG_TRACE("g_mqtt_signout.hostname: %s",g_mqtt_signout.hostname);

memset(&mqtt_params,0,sizeof(iotx_mqtt_param_t));

mqtt_params.port = g_mqtt_signout.port; mqtt_params.host = g_mqtt_signout.hostname; mqtt_params.client_id = g_mqtt_signout.clientid; mqtt_params.username = g_mqtt_signout.username; mqtt_params.password = g_mqtt_signout.password;

mqtt_params.request_timeout_ms = 2000; mqtt_params.clean_session = 0; mqtt_params.keepalive_interval_ms = 60000; mqtt_params.read_buf_size = 1024; mqtt_params.write_buf_size = 1024;

mqtt_params.handle_event.h_fp = example_event_handle; mqtt_params.handle_event.pcontext = NULL;

g_mqtt_handle = IOT_MQTT_Construct(&mqtt_params); if (g_mqtt_handle != NULL){ g_mqtt_connect_status = 1;

文档版本:20200417 365

Page 378: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

DEBUG_TRACE("IOT_MQTT_Construct Success"); } } }

比较特别的是

• 在异步模式下, 如果 IOT_MQTT_Construct() 返回成功, 仅表示socket连接函数调用成功, 而不代

表MQTT长连接已经建立

• 调用结果是通过 MSG_ID_APP_SOC_NOTIFY_IND 事件返回的, 由上面提到的 mqtt_task_main()

任务处理

void mqtt_task_main(task_entry_struct *task_entry_ptr) { ... while(1) { receive_msg_ext_q( task_info_g[task_entry_ptr->task_indx].task_ext_qid, &current_ilm); stack_set_active_module_id(my_index, current_ilm.dest_mod_id); switch (current_ilm.msg_id) { case MSG_ID_APP_SOC_NOTIFY_IND: { ERROR_TRACE("%s,%d", __FUNCTION__,__LINE__); ali_socket_notify(current_ilm.local_para_ptr); break; }

TCP连接建立成功时, 调用SDK提供的接口 IOT_MQTT_Nwk_Event_Handler() 建立MQTT连接

TCP建连成功时, Nucleus系统会产生 SOC_CONNECT 事件, 我们编写了 ali_socket_notify() 函数包

装 IOT_MQTT_Nwk_Event_Handler()

void ali_socket_notify(void *msg_ptr){ ... switch (soc_notify->event_type) { ... case SOC_CONNECT: { DEBUG_TRACE("Ali SOC_CONNECT Event"); ret = IOT_MQTT_Nwk_Event_Handler(g_mqtt_handle, IOTX_MQTT_SOC_CONNECTED ,&nwk_param); if (ret == SUCCESS_RETURN) { g_mqtt_connect_status = 2; DEBUG_TRACE("Aliyun connect success,start yield"); example_subscribe(g_mqtt_handle); StopTimer(ALIYUN_YIELD_TIMER); StartTimer(ALIYUN_YIELD_TIMER,1000*2,ali_mqtt_yield); } }

366 文档版本:20200417

Page 379: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

以上的代码除了通过 IOTX_MQTT_SOC_CONNECTED 事件驱动 IOT_MQTT_Nwk_Event_Handler()

建立MQTT连接, 也订阅了Topic, 并启动了定时器 ali_mqtt_yield() 来维持心跳

启动心跳定时器, 调用SDK提供的接口 IOT_MQTT_Yield() 维持长连接

void ali_mqtt_yield(void){ static int send_interval = 0; DEBUG_TRACE("ali_mqtt_yield..."); IOT_MQTT_Yield(g_mqtt_handle,200);

send_interval+=5; if (send_interval == 20) { send_interval = 0; example_publish(g_mqtt_handle); } StartTimer(ALIYUN_YIELD_TIMER,1000*5,ali_mqtt_yield);}

在异步模式下, IOT_MQTT_Yield() 已经变得 只发不收 了, 它只会起到维持心跳的作用

在心跳的定时器中, 调用SDK提供的接口 IOT_MQTT_Publish() 发出上行的报文消息给自己

int example_publish(void *handle){ int res = 0; iotx_mqtt_topic_info_t topic_msg; char product_key[IOTX_PRODUCT_KEY_LEN] = {0}; char device_name[IOTX_DEVICE_NAME_LEN] = {0}; const char *fmt = "/%s/%s/get"; char topic[128] = {0}; char *payload = "hello,world";

HAL_GetProductKey(product_key); HAL_GetDeviceName(device_name);

HAL_Snprintf(topic, 128, fmt, product_key, device_name);

memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t)); topic_msg.qos = IOTX_MQTT_QOS0; topic_msg.retain = 0; topic_msg.dup = 0; topic_msg.payload = (void *)payload; topic_msg.payload_len = strlen(payload);

res = IOT_MQTT_Publish(handle, topic, &topic_msg); if (res < 0) { DEBUG_TRACE("publish failed\n"); return -1; } return 0;}

文档版本:20200417 367

Page 380: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

由于例程所使用的设备是特别在控制台配置过的, 它的 /${productKey}/${deviceName}/get 可订阅

也可发布, 我们前面建连成功时已经订阅了它, 现在又向它发送报文, 因此可以看到

通过协议栈底层驱动, 接收被订阅Topic上的报文

这仍然是通过包装了 IOT_MQTT_Nwk_Event_Handler() 的 ali_socket_notify() 函数来处理的

void ali_socket_notify(void *msg_ptr){ ... switch (soc_notify->event_type) { case SOC_READ: { DEBUG_TRACE("Ali SOC_READ Event"); IOT_MQTT_Nwk_Event_Handler(g_mqtt_handle,IOTX_MQTT_SOC_READ,&nwk_param); DEBUG_TRACE("Ali SOC_READ End"); } break;

当有数据可读的时候, Nucleus的协议栈会以 SOC_READ 事件通知, 在此如果不想做其它处理, 直接用

IOT_MQTT_Nwk_Event_Handler() 交给SDK, 即可分发给当初订阅相应Topic时注册的函数处理

烧录固件

在本示例程序的开发环境中, 编译固件的环境是

368 文档版本:20200417

Page 381: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

打开 cmd.exe 命令行, 通过MTK提供的编译脚本启动固件的构建过程

然后将编译出来的固件用 FlashTool 工具烧录到设备上

文档版本:20200417 369

Page 382: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 选择 config file, 在 build 目录下后缀 .cfg结尾文件

• 选择 option 设置, 第一次烧录或有异常问题时, 勾选 Format FAT

• 点击 download, 将设备的USB口连接电脑即开始下载

370 文档版本:20200417

Page 383: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

观察运行效果

打开 Catcher 调试工具, 由于 MOD_NIL 标记下的日志较少, 例程的日志打印到 MOD_NIL 这

个filter上, 对其筛选可查看例程输出的日志

用串口工具操作GPRS设备连网成功, 例程则开始工作, 可在 Catcher 中观察到它建立MQTT连接, 订

阅, 发布和接收到报文过程中的日志

文档版本:20200417 371

Page 384: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

同时若登录到IoT云端控制台(https://iot.console.aliyun.com), 也可以看到对应的设备上线, 并看到

它发上来的报文, 表明接入成功

1.2.1.5.8 高级系统集成SDK

1.2.1.5.8.1 目标系统为64位Linux其中有三个主要产物, 它们都是64位架构的:

C-SDK对其HAL和TLS都已有官方提供的参考实现, 因此可以完整

编译出所有的库和例子程序

选择平台配置

make reconfig

SELECT A CONFIGURATION:

1) config.alios.esp82662) config.alios.mk30803) config.ubuntu.x86#? 3

SELECTED CONFIGURATION:

VENDOR : ubuntuMODEL : x86......

372 文档版本:20200417

Page 385: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

编译

make

获取二进制库

cd output/release/libls

产物文件名 说明

libiot_hal.a HAL接口层的参考实现, 提供了 HAL_XXX() 接口

libiot_sdk.a SDK的主库, 提供了 IOT_XXX 接口和 linkkit_xxx() 接口

libiot_tls.a 裁剪过的 mbedtls, 提供了 mbedtls_xxx() 接口,支撑 libiot_hal.a

获取可执行程序

cd output/release/binls

其中有两个主要产物, 它们都是64位架构的:

产物文件名 说明

linkkit-example-solo 高级版(旧版API)的例程, 可演示 linkkit_xxx() 接口的使用

mqtt-example 基础版的例程, 可演示 IOT_XXX() 接口的使用

1.2.1.5.8.2 目标系统为32位Linux安装32位工具链

如果您编译SDK是在一台安装了32位 Linux 的机器上, 那么参考

目标系统为64位Linux 的步骤, 即可得到32位的库和例程

如果您是在安装了64位 Ubuntu16.04 的机器上, 需要编译出32位

的库, 请按照下文操作

sudo apt-get install -y libc6:i386 libstdC++6:i386 gcc:i386

文档版本:20200417 373

Page 386: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

修改平台配置文件

vim src/board/config.ubuntu.x86

增加如下一行

CONFIG_ENV_CFLAGS += -m32

比如:

cat src/board/config.ubuntu.x86

CONFIG_ENV_CFLAGS += \ -Os -Wall \ -g3 --coverage \ -D_PLATFORM_IS_LINUX_ \ -D__UBUNTU_SDK_DEMO__ \

...

...CONFIG_ENV_LDFLAGS += -lpthread -lrt

CONFIG_ENV_LDFLAGS += -m32OVERRIDE_STRIP := strip

选择平台配置

make reconfigSELECT A CONFIGURATION:

1) config.macos.make 3) config.ubuntu.x862) config.rhino.make 4) config.win7.mingw32#? 3

编译

make

获取二进制库

cd output/release/libls

其中有三个主要产物, 它们都是32位架构的:

产物文件名 说明

libiot_hal.a HAL接口层的参考实现, 提供了 HAL_XXX() 接口

374 文档版本:20200417

Page 387: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

产物文件名 说明

libiot_sdk.a SDK的主库, 提供了 IOT_XXX 接口和 linkkit_xxx() 接口

libiot_tls.a 裁剪过的 mbedtls, 提供了 mbedtls_xxx() 接口,支撑 libiot_hal.a

获取可执行程序

cd output/release/binls

其中有两个主要产物, 它们都是32位架构的:

产物文件名 说明

linkkit-example-solo 高级版(旧版API)的例程, 可演示 linkkit_xxx() 接口的使用

mqtt-example 基础版的例程, 可演示 IOT_XXX() 接口的使用

可以用如下方式验证, 注意 file 命令的输出中, 已经显示程序都是32位的了(ELF 32-bit LSB

executable)

file output/release/bin/*

output/release/bin/linkkit-example-countdown: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/linkkit-example-sched: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/linkkit-example-solo: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/linkkit_tsl_convert: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/mqtt-example: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/mqtt-example-multithread: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/mqtt-example-rrpc: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/ota-example-mqtt: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/sdk-testsuites: ELF 32-bit LSB executable, Intel 80386, ... strippedoutput/release/bin/uota_app-example: ELF 32-bit LSB executable, Intel 80386, ... stripped

文档版本:20200417 375

Page 388: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

使用cmake方式编译

修改 CMakeLists.txt 文件

在默认的文件中修改CFLAGS, 加入-m32

SET (CMAKE\_C\_FLAGS " -Iexamples -Os -Wall")

改成

SET (CMAKE\_C\_FLAGS " -Iexamples -Os -Wall -m32")

从 CMakeLists.txt 构建makefile

mkdir ooocd ooocmake ..

编译

make -j32

产物

~/srcs/iotx-sdk-c/ooo\$ lsbin CMakeCache.txt CMakeFiles cmake\_install.cmake examples lib Makefile src tests

可执行程序在 bin/ 目录下:

ls bin/

linkkit-example-countdown linkkit-example-sched linkkit-example-solo linkkit\_tsl\_convertmqtt-example mqtt\_example\_multithread mqtt\_example\_rrpc ota-example-mqtt uota\_app-example

可以用如下方式验证, 注意 file 命令的输出中, 已经显示程序都是32位的了(ELF 32-bit LSB

executable)

file ooo/bin/\*

ooo/bin/linkkit-example-countdown: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/linkkit-example-sched: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/linkkit-example-solo: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/linkkit\_tsl\_convert: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/mqtt-example: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/mqtt-example-multithread: ELF 32-bit LSB executable, Intel 80386, ... stripped

376 文档版本:20200417

Page 389: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

ooo/bin/mqtt-example-rrpc: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/ota-example-mqtt: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/sdk-testsuites: ELF 32-bit LSB executable, Intel 80386, ... strippedooo/bin/uota\_app-example: ELF 32-bit LSB executable, Intel 80386, ... stripped

二进制库在 lib/ 目录下:

ls lib/

libiot\_hal.so libiot\_sdk.so libiot\_tls.so

1.2.1.5.8.3 目标系统为arm-linux以如下命令和输出确认交叉编译工具链已安装好

sudo apt-get install -y gcc-arm-linux-gnueabihf

arm-linux-gnueabihf-gcc --version

arm-linux-gnueabihf-gcc (Ubuntu/Linaro 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609Copyright (C) 2015 Free Software Foundation, Inc.

创建平台配置文件

vim tools/board/config.arm-linux.demo

CONFIG_ENV_CFLAGS = \ -D_PLATFORM_IS_LINUX_ \ -Wall \ -DNO_EXECUTABLES \

CONFIG_ENV_LDFLAGS = \ -lpthread -lrt \

OVERRIDE_CC = arm-linux-gnueabihf-gccOVERRIDE_AR = arm-linux-gnueabihf-arOVERRIDE_LD = arm-linux-gnueabihf-ld

CONFIG_wrappers :=

或者写成

CONFIG_ENV_CFLAGS = \ -D_PLATFORM_IS_LINUX_ \ -Wall \ -DNO_EXECUTABLES \

CONFIG_ENV_LDFLAGS = \ -lpthread -lrt \

CROSS_PREFIX := arm-linux-gnueabihf-

文档版本:20200417 377

Page 390: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

CONFIG_wrappers :=

选择平台配置

make reconfig

SELECT A CONFIGURATION:

1) config.alios.mk30802) config.arm-linux.demo3) config.ubuntu.x86#? 2

SELECTED CONFIGURATION:

VENDOR : arm-linuxMODEL : demo

编译

make

获取二进制库

cd output/release/libls

其中有两个主要产物, 它们都是arm-linux架构的:

产物文件名 说明

libiot_sdk.a SDK的主库, 提供了 IOT_XXX 接口和 linkkit_xxx() 接口

libiot_tls.a 裁剪过的 mbedtls, 提供了 mbedtls_xxx() 接口,支撑 libiot_hal.a

1.2.1.5.8.4 在Windows下编译SDK用户可以配置需要的SDK功能,将相关的源文件从SDK中抽取出来,然后将抽取出来的代码加入到自

己的编译环境进行编译即可。如何抽取自己需要的源文件取用, 详见文档: 基于代码抽取时的移植过程

1.2.1.5.9 windows

378 文档版本:20200417

Page 391: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.5.9.1 安装Eclipse开发环境本文描述如何在Windows下安装Eclipse、MSYS2和MINGW来开发和编译C语言程序。

获取和安装Eclipse

1. 请访问Eclipse官网安装Eclipse,本文档编写时下载了Eclipse 2019年3月份的64位版

本installer:

文档版本:20200417 379

Page 392: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. 选择安装用于C/C++开发的IDE:

获取和安装MSYS2

MSYS2在Windows下提供一个类似Linux的环境,可以让熟悉Linux环境的开发者在Windows下比较

方便的安装和使用Linux环境下常用的命令和开发工具。

1. 请访问MSYS2官网

说明:

本文编写时因为使用的笔记本电脑是64位系统,所以安装了msys2-x86_64,编写时的msys版本

为msys2-x86_64-20180531.exe,下面涉及MSYS2的页面截图均基于该版本。

380 文档版本:20200417

Page 393: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. 安装完MSYS2之后,运行MSYS2。

文档版本:20200417 381

Page 394: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

3. 在MSYS2中运行命令pacman -Syu,对软件包进行更新。

第一次更新时会提示关闭MSYS2之后再次打开MSYS2的提示,如下图所示。

此时需要将MSYS2关闭再重新打开,然后再次运行命令 pacman -Syu 对软件包进行更新。

382 文档版本:20200417

Page 395: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

获取和安装MINGW64

MSYS2软件包更新之后并没有安装MINGW,因此没有gcc、make等开发工具,因此还需要

在MSYS2的shell中输入命令 pacman -S mingw-w64-x86_64-toolchain 进行MINGW的安装,如

下图所示。

直接回车对所有相关工具进行安装。

MINGW安装完之后在MINGW的“bin”目录下具有文件“mingw32-make.exe”,但是eclipse编

译时会调用“make”,因此需要将该文件复制并重命名为“make.exe”,修改完毕之后如下图所

示。

修改Windows环境变量

虽然已经安装了MSYS2和MINGW,但是并没有将MSYS2和MINGW提供的工具加入Windows的PATH

目录,eclipse编译程序时调用gcc、make还是会失败,因此需要对Windows的环境变量进行修改。

文档版本:20200417 383

Page 396: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1. 打开控制面板 > 系统和安全 > 系统,然后点击窗口左边的高级系统设置,如下图所示。

2. 修改“PATH”,如下图所示。

3. 在PATH的最后把MSYS2的usr/bin和MINGW的bin绝对路径加入进去,并点击确定。

说明:

本文编写时MSYS2安装在D:\msys64目录,因此加入PATH的内容为D:\msys64\usr\bin;D:\

msys64\mingw64\bin,用户需要根据自己安装MSYS2的目录进行相应修改。

384 文档版本:20200417

Page 397: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

验证开发环境

安装完MSYS2和MINGW之后,需要验证Eclipse是否可以正常编译C程序。

1. 运行Eclipse并新建一个C工程,选择使用C Managed Build,如下图所示。

文档版本:20200417 385

Page 398: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. 点击“Next”按钮之后,输入工程名称、选择创建“Hello World ANSI C Project”、并指

定Toolchain使用MinGW,如下图所示。

386 文档版本:20200417

Page 399: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

3. 点击按钮“Finish”完成工程创建。在新建的工程上鼠标右键单击并选择“Build Project”后对

工程进行编译,如下图所示。

如果前面的设置一切正确,那么编译将会成功,编译的输出内容将会类似下面的示例。

文档版本:20200417 387

Page 400: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

4. 编译完毕之后,可以运行程序,可以点击工具栏中的运行按钮,如下图左上角框选的箭头按钮。

运行成功之后的输出将显示Console窗口中,如上图中右边框选的输出内容。

1.2.1.5.9.2 使用MQTT Topic与物联网平台通信概述

本文讲解如何移植Link Kit SDK到Windows操作系统,在Windows下运行demo程序连接到阿里云

物联网平台,本文的示例中将涉及以下功能点:

• 使用MQTT连接阿里云物联网平台,连接使用TLS进行加密。

• 使用一机一密方式对设备进行认证。

• 如何使用MQTT TOPIC进行数据收发。

• 如何实现相关HAL。

开发环境描述

操作系统版本 Win7

IDE Eclipse IDE for C/C++ Developers,版本:2019-03 (4.11.0)

388 文档版本:20200417

Page 401: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

操作系统版本 Win7

包管理工具 MSYS2

Toolchain mingw-w64-x86_64-toolchain

TLS库 openssl,版本1.1.1.b-1

说明:

若用户未安装Eclipse开发环境,可参考Eclipse开发环境安装

请确认开发环境中openssl已安装,在MSYS2的命令行工具中输入。

pacman -Sl |grep openssl

确保输出的内容中,如下图框选的openssl库显示已安装。

前置文档

在开始实际开发之前请务必阅读以太网设备接入过程说明,了解基本概念。

示例产品功能描述

示例产品连接到阿里云物联网平台之后,将会订阅TOPIC “/${ProductKey}/${deviceName}/user/

get”的数据,然后每4秒发送一个消息到该topic,意味着这个消息会被发送到物联网平台,然后由

于设备自己订阅了这个topic,因此设备发送到物联网平台的消息将会被平台发送给设备。

文档版本:20200417 389

Page 402: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

因此从设备的角度来看,示例产品的功能就是将消息发送到物联网平台,并将其接收回来。

云端操作

• 创建以太网产品

可参见操作示例。

• 创建调试设备

可参见操作示例。

• 修改topic属性

示例代码中使用到的Topic “/${ProductKey}/${deviceName}/user/get”默认只有“订阅权

限”,需要将其修改为“发布和订阅”,因为设备将会发送消息到这个topic。修改后的显示如下

所示。

390 文档版本:20200417

Page 403: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

说明:

用户创建的产品用于ProductKey将会与示例不同,因此上图中Topic中的a1a840P0BS3将会显示用

户创建产品的ProductKey。

设备端开发过程

1. SDK获取。

点击此处

说明:

本文基于SDK3.0.1进行编写,为了避免代码存在差异,建议用户使用同样的版本进行体验。

文档版本:20200417 391

Page 404: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. SDK配置。

因为不同的SDK功能依赖的HAL不一样,为了减少设备开发时对接HAL的数量,开发者只需要选中

需要支持的功能即可。

运行SDK根目录下的config.bat,进行SDK功能配置。

请确保以下选项被选中,如上图所示。

• PLATFORM_HAS_STDINT

• PLATFORM_HAS_DYNMEM

• PLATFORM_HAS_OS

• FEATURE_MQTT_COMM_ENABLED

- FEATURE_MQTT_DEFAULT_IMPL

- FEATURE_MQTT_DIRECT

• FEATURE_SUPPORT_TLS

配置完成后点击按钮Exit,配置工具会提示是否保存配置,选择Yes即可

392 文档版本:20200417

Page 405: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

3. Eclipse工程创建与配置。

a) 在Eclipse IDE中创建一个Eclipse C工程。

b) 点击Next按钮后,对工程进行命名,设置Toolchains,如下图所示。

文档版本:20200417 393

Page 406: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

c) 点击按钮Finish完成工程创建后,右键单击工程显示如下所示的菜单。

394 文档版本:20200417

Page 407: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

d) 点击Import后跳出下面的Import窗口。

文档版本:20200417 395

Page 408: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

e) 选择File System后,点击按钮Next,然后Eclipse将会提示输入需要导入的路径,请将上一节

中生成的output目录进行导入,如下图所示。

396 文档版本:20200417

Page 409: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中mqtt_example.c是SDK中提供的示例代码,在本文中将其加入进行验证使用。

f) 点击按钮Finish之后,Eclipse将会把output下面的相关代码复制

到Eclipse的workspace中,如下图所示。

文档版本:20200417 397

Page 410: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

g) 在工程上右键单击显示菜单,并点击Properties按钮。

398 文档版本:20200417

Page 411: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

h) 点击Properties按钮之后,将会显示Properties窗口,选择C/C++ Build > Settings。

文档版本:20200417 399

Page 412: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

i) 将相关路径加入之后,再选择MinGW C Linke > Libraries,将wsock32和ssl加入,如下图所

示。

j) 点击窗口下方的Apply and Close结束配置Eclipse的工程配置。

400 文档版本:20200417

Page 413: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

4. HAL实现。

wrapper.c里面包含SDK运行时需要目标平台进行支持的HAL函数,这些函数抽取出来之后函数体

并没有进行实现,需要开发者进行实现。

这里是该wrapper.c的参考实现

注意:

用户需要将wrapper.c中下面的HAL函数中的内容替换为自己创建的产品和设备的信息:

• HAL_GetProductKey

• HAL_GetDeviceName

• HAL_GetDeviceSecret

文档版本:20200417 401

Page 414: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

5. 编译与调试。

• 设备端

a. 右键单击工程显示菜单,并点击其中的“Build Project”,如下图所示。

如果一切正常,编译完成之后在Eclipse的console中会显示编译结束,如下图所示。

b. 在Eclipse之中将项目以“Local C/C++ Application”运行,下面是正确运行时

的console中的显示。

402 文档版本:20200417

Page 415: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中,mqtt Connect Success表示MQTT连接云端成功,设备认证已通过。

mqtt_example.c会订阅Topic/${ProductKey}/${deviceName}/user/get,并把消息发送

给这个Topic,因此设备将会把自己发送给物联网平台的消息接收回来,在Console中的显

示如下图所示。

上图中圈选的PUBLISH是设备发送给物联网平台的消息,圈选的Payload:{“nessage”:”

hello!”}是设备从物联网平台接收到的消息。

• 物联网平台端

文档版本:20200417 403

Page 416: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

- 开发者也可以在物联网平台端查看设备的状态,当设备连接到物联网平台时,设备的状态将

会显示为“在线”,如下图所示。

- 开发者也可以点击“日志服务”查看设备向物联网平台上报的消息、以及物联网平台发送给

设备的消息,如下图所示。

文档参考

当设备可以连接到物联网平台之后,用户会进行自己的产品逻辑的编写,请参考下面的章节了解更多

细节。

• 设备认证编程指南

• 自定义MQTT Topic编程指南

1.2.1.5.9.3 物模型编程接入LP-无TLS加密本文讲解如何移植Link Kit SDK到Windows操作系统,在Windows下运行demo程序连接到阿里云

物联网平台,本文的示例中将涉及以下功能点:

• 使用MQTT连接阿里云物联网平台,不使能TLS加密

• 使用一机一密方式对设备进行认证

404 文档版本:20200417

Page 417: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 属性上报、事件上报

• 如何实现相关HAL

注:基于Link Kit SDK 3.0.1版本编写

开发环境描述

操作系统版本 Win7

IDE Eclipse IDE for C/C++ Developers,版本:2019-03 (4.11.0)

包管理工具 MSYS2

Toolchain mingw-w64-x86_64-toolchain

注:若用户未安装Eclipse开发环境,可参考Eclipse开发环境安装了解如何安

装Eclipse、MSYS2、MinGW来在Windows环境下编译C程序。

前置文档

在开始实际开发之前请务必阅读以下文档:

• 以太网设备接入过程说明,了解基本概念

Example程序功能描述

示例程序(output\examples\linkkit_example_solo.c)连接到阿里云物联网平台之后,将会每2

秒钟上报一次设备的属性,每10次上报一次事件到物联网平台。

云端操作

• 创建以太网产品

可参见操作示例了解如何创建产品,并获取产品的ProductKey、ProductSecret。

为了快速创建与示例代码功能匹配的产品功能定义,用户可以将示例产品的物模型定义(_src\

dev_model\examples\model_for_examples.json_)导入物联网平台,请参见“[导入物模型](

https://help.aliyun.com/document_detail/116943.html)”了解操作步骤。

• 创建调试设备

可参见操作示例了解如何创建调试设备,并获取设备的DeviceName、DeviceSecret

设备端开发过程

SDK获取

点击此处获取Link Kit SDK3.0.1代码

文档版本:20200417 405

Page 418: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

SDK配置

因为不同的SDK功能依赖的HAL不一样,为了减少设备开发时对接HAL的数量,开发者只需要选中需

要支持的功能即可。

运行SDK根目录下的config.bat,进行SDK功能配置:

请确保以下配置被选中:

• PLATFORM_HAS_STDINT

• PLATFORM_HAS_DYNMEM

• PLATFORM_HAS_OS

• FEATURE_MQTT_COMM_ENABLED

- FEATURE_MQTT_DEFAULT_IMPL

- FEATURE_MQTT_DIRECT

• FEATURE_DEVICE_MODEL_ENABLED

功能配置之后,选择“Exit”,并进行配置保存

SDK代码抽取

运行SDK根目录下的extract.bat,将选中功能的代码抽取出来,如下图所示:

406 文档版本:20200417

Page 419: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

抽取出来的代码将放置在SDK的output目录下。

Eclipse工程创建与配置

在Eclipse IDE中创建一个Eclipse C工程:

文档版本:20200417 407

Page 420: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击Next按钮后,对工程进行命名,设置Toolchains,如下图所示:

点击Finish按钮,完成工程创建后,右键单击工程显示工程菜单:

408 文档版本:20200417

Page 421: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击“Import”按钮后跳出下面的“Import”窗口:

文档版本:20200417 409

Page 422: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在“General”中选择“File System”,然后点击“Next”按钮:

410 文档版本:20200417

Page 423: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击上图中的“Browse...”按钮去选择SDK抽取出来的output目录,将output目录下的eng下的所

有子目录均选中,如上图所示; output目录下的examples目录只选中linkkit_example_solo.c,如

上图右边的橙色框所示。

点击“Finish”按钮后,Eclipse将把相关代码复制到Eclipse的工程下面,如下图所示:

文档版本:20200417 411

Page 424: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在工程上右键单击显示菜单,并点击“Properties”按钮:

412 文档版本:20200417

Page 425: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击“Properties”按钮之后,将会显示如下图所示的窗口:

文档版本:20200417 413

Page 426: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在窗口左边的树形菜单中选择“C/C++ Build”-> “Settings”,在右边的“Settings”中设置编译

时头文件查找目录,将output/eng下的所有目录、output\eng下面的sdk_include.h加入进去,并

点击窗口下方的“Apply”按钮保存配置。

继续点击“Settings”窗口中的“Libraries”菜单,把库“wsock32”加入,加入后的显示如下图所

示:

414 文档版本:20200417

Page 427: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

然后点击窗口下方的“Apply and Close”结束配置

HAL实现

wrapper.c里面包含SDK运行时需要目标平台进行支持的HAL函数,这些函数需要开发者进行实现

本文提供了wrapper.c参考实现,需要注意的是开发者一定需要将下面的HAL进行修改来返回设备的

身份信息:

• HAL_GetProductKey()

• HAL_GetProductSecret()

• HAL_GetDeviceName()

文档版本:20200417 415

Page 428: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• HAL_GetDeviceSecret()

编译与调试

设备端

右键单击项目显示菜单,并点击其中的“Build Project”,如下图所示:

如果一切正常,编译完成之后在Eclipse的console中会显示:

然后在Eclipse之中将项目以“Local C/C++ Application”运行,下面是正确运行时的console中的

显示:

416 文档版本:20200417

Page 429: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中:“mqtt Connect Success”表示MQTT连接云端成功,设备认证已通过

物联网平台端

开发者也可以在物联网平台上查看设备的运行状态,如果设备已正常连接云端,那么云端显示如下图

所示:

点击“运行状态”,可以看见设备端上报属性的时间,以及当前counter的数值,如下图所示:

文档版本:20200417 417

Page 430: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击TAB“事件管理”,可以看见设备上报事件的时间以及内容,如下图所示

文档参考

• 设备认证编程指南

• 物模型编程指南

1.2.1.5.9.4 以太网灯接入飞燕示例本文讲解如何移植Link Kit SDK 3.0.1到Windows操作系统,并在Windows下实现一个虚拟的灯连接

到阿里云飞燕平台(生活物联网平台)。本文的示例将涉及以下功能点:

• 使用MQTT接入阿里云飞燕平台,MQTT连接使用TLS加密

• 使用一机一密方式对设备进行认证

• 通过物模型实现一个灯的功能

• 如何实现相关HAL

• 使用飞燕调试APP绑定设备并进行控制

418 文档版本:20200417

Page 431: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

开发环境描述

操作系统版本 Win7

IDE Eclipse IDE for C/C++ Developers,版本:2019-03 (4.11.0)

包管理工具 MSYS2

Toolchain mingw-w64-x86_64-toolchain

注:若用户未安装Eclipse开发环境,可参考Eclipse开发环境安装了解如何安

装Eclipse、MSYS2、MinGW,之后可以在Windows环境下编译C程序。

示例灯功能描述

示例程序ilop_demo_light.c用于在Windows上模拟一个灯,设备厂商可以将该文件下载后作为参

考,该灯的功能如下:

• 灯的状态默认为关闭状态

• 灯连接到阿里云物联网平台后,将会把灯的状态上报到云端

• 灯将会接收来自飞燕的控制命令,对灯进行打开或者关闭的操作,并将灯的最新状态上报云端

• 在灯上创建了一个线程用于监控灯的温度,如果灯温度大于或者等于80度则报警,告诉云端灯的

温度过高。灯的温度值初始为83度,每10秒降低一度,当温度小于80度后,告知云端设备运行正

常。

云端操作

• 创建以太网产品

• 创建调试设备

可参见操作示例了解如何创建以太网灯产品和调试设备,并获取设备

的ProductKey、ProductSecret、DeviceName、DeviceSecret。

设备端开发过程

SDK获取

点击此处去获取Link Kit SDK3.0.1代码

SDK配置

因为不同的SDK功能依赖的HAL不一样,为了减少设备开发时对接HAL的数量,开发者只需要选中需

要支持的功能即可。

文档版本:20200417 419

Page 432: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

运行SDK根目录下的config.bat,进行SDK功能配置:

请确保以下配置被选中:

• PLATFORM_HAS_STDINT

• PLATFORM_HAS_DYNMEM

• PLATFORM_HAS_OS

• FEATURE_INTRA_NETWORK_PAYLOAD

• FEATURE_INTRA_LOG

- MUTE_LEVEL_of_FLOW

- MUTE_LEVEL_of_DEBUG

- MUTE_LEVEL_of_INFO

- MUTE_LEVEL_of_WARNING

- MUTE_LEVEL_of_ERROR

- MUTE_LEVEL_of_CRIT

• FEATURE_MQTT_COMM_ENABLED

- FEATURE_MQTT_DEFAULT_IMPL

- FEATURE_MQTT_DIRECT

• FEATURE_DEVICE_MODEL_ENABLED

• FEATURE_SUPPORT_TLS

• FEATURE_DEV_RESET

• FEATURE_DEV_BIND_ENABLED

420 文档版本:20200417

Page 433: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

功能配置之后,选择“Exit”,并进行配置保存

SDK代码抽取

运行SDK根目录下的extract.bat,将选中功能的代码抽取出来,如下图所示:

抽取出来的代码将放置在SDK的output目录下。

Eclipse工程创建与配置

在Eclipse IDE中创建一个Eclipse C工程:

文档版本:20200417 421

Page 434: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击Next按钮后,对工程进行命名,设置Toolchains,如下图所示:

422 文档版本:20200417

Page 435: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击Finish按钮,完成工程创建后,右键单击工程显示工程菜单:

文档版本:20200417 423

Page 436: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击“Import”按钮后跳出下面的“Import”窗口:

424 文档版本:20200417

Page 437: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在“General”中选择“File System”,然后点击“Next”按钮,并将output\eng下面的所有目录

选中,如下图所示:

文档版本:20200417 425

Page 438: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击“Finish”按钮后,Eclipse将把SDK的相关代码复制到Eclipse的工程下面。请使用同样的方法

将下载的文件ilop_demo_light.c导入工程,文件添加结束之后的工程如下所示:

426 文档版本:20200417

Page 439: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在工程上右键单击显示菜单,并点击“Properties”按钮:

文档版本:20200417 427

Page 440: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击“Properties”按钮之后,将头文件所在目录进行指定,请参照下面的图示将相关目录添加到

includes:

428 文档版本:20200417

Page 441: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

配置完成之后,并点击窗口下方的“Apply”按钮保存配置。

继续点击“Settings”窗口中的“Libraries”菜单,对需要使用到的库进行设置,如下图所示:

文档版本:20200417 429

Page 442: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

配置完成后点击窗口下方的“Apply and Close”结束配置

HAL实现

wrapper.c里面包含SDK运行时需要目标平台进行支持的HAL函数,这些函数需要开发者进行实现

这里是该wrapper.c中HAL的参考实现,开发者可以将该文件下载之后将工程中wrapper.c的内容进

行替换。下面是替换之后仍然需要用户修改或者注意的地方:

设备身份获取

参考实现的wrapper.c中函数HAL_GetProductKey()、HAL_GetProductSecret()、HAL_GetDev

iceName()、HAL_GetDeviceSecret()直接返回了调试设备的上述身份信息,设备厂商需要对这几个

函数进行重新实现。

比如在产线上为了快速的将设备的三元组到设备,产线可以将设备的身份信息加密之后写入到某个文

件并烧写到设备的文件系统,设备上电之后需要使用设备厂商定义的解密方法从这个文件中将设备的

身份信息读取出来,因此设备厂商的就需要重新实现上述HAL从加密文件中读取指定内容。

网络接口指定

设备可能具备多个网络接口,参考实现中的函数HAL_Wifi_Get_IP()、HAL_Wifi_Get_Mac()从指定的

一个网络接口去读取IP地址和MAC地址,因此设备厂商需要将wrapper.c中的接口名修改为设备的接

口名:

static wchar_t* gIfName = L"\\DEVICE\\TCPIP_{C9E93150-C6B1-4B15-8A2E-C08747261CD2}";

430 文档版本:20200417

Page 443: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

KV文件指定

SDK在运行的时候有些配置会进行保存,将会调用函数HAL_Kv_Set()、HAL_Kv_Get()进行配置的保

存和读取。由于需要保存的数据并不多,在参考实现中配置是按照一行保存一个配置的方式进行实

现,并写入到了下面定义的文件:

static char *kvFileName="c:\\iotKv.data";

设备厂商需要将kvFileName指向一个非易失文件系统中的文件,也即设备重启该文件中的内容不会

丢失。

示例产品代码说明

本节对ilop_demo_light.c中的关键代码进行说明。

主程序说明

在main()函数中:

• 注册事件处理函数

• 调用IOT_Linkkit_Open()创建设备ID;

• 调用IOT_Linkkit_Connect()连接阿里云;

• 创建一个while(1)循环,在其中调用IOT_Linkkit_Yield去接收来自云端的数据

其中添加事件处理函数的语句如下:

/* Register Callback for events*/ IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler); IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler); IOT_RegisterCallback(ITE_SERVICE_REQUEST, user_service_request_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_TRIGGER_EVENT_REPLY, user_trigger_event_reply_event_handler); IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_event_handler); IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized); IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler); IOT_RegisterCallback(ITE_COTA, user_cota_event_handler);

上面的代码中将常见的事件都进行了注册,厂商在开发时只需要对相应的函数体进行修改即可。

下面是创建设备ID以及连接云端的代码片段:

文档版本:20200417 431

Page 444: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

需要注意的是:

• IOT_Linkkit_Connect()如果返回失败,SDK不会再次尝试连接云端,因此上图的第二个橙色框选

部分,如果失败了之后会每过一秒再次调用连接函数来确保连接成功

• 如果IOT_Linkkit_Connect()成功后,设备与云端的连接出现异常断开,那么SDK会自动尝试与云

端重新建立连接,在这种情况下厂商无需调用IOT_Linkkit_Connect()去连接物联网平台

• 第三个橙色圈选部分,调用了IOT_Linkkit_Yield()去收包、以及是否需要与云端保持激活等公牛,

HAL_SleepMs(200)是指每次调用IOT_Linkkit_Yield()之后等待200毫秒,如果一个设备的数据收

发量很大,那么可以缩短HAL_SleepMs()等待的时间

• 如果一个设备与云端的数据收发量非常大,通过缩短HAL_SleepMs()等待间隔导致设备功耗很大

或者效率不高,可以参考SDK的同步与异步通信中描述的异步通信方式进行数据收发。

设备连接到云端后的处理

在示例代码中,当设备通过认证并连接到云端后会调用回调函数user_connected_event_handler

,该函数的内容如下:

432 文档版本:20200417

Page 445: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中user_post_property()用于上报设备的各个属性的最新状态到云端,厂商在开发产品时需要根据

自己的产品具有的属性来对该函数进行修改。

示例代码当设备连接到云端之后,还启动了一个线程用于周期的上报事件,厂商在实际产品开发

时,应该在该线程中监控设备是否有属性发生了变化(比如用户手动进行开灯、关灯操作),如果有

属性发生变化时将变化了的属性上报云端;同时该线程还应检测设备是否工作异常,如果异常需要将

异常通过事件上报云端

属性上报的代码说明

在示例代码中调用函数user_post_property()进行了属性上报,函数代码如下所示:

其中IOT_Linkkit_Report()用于向云端发送数据,其中参数ITM_MSG_POST_PROPERTY表示上报的是

设备属性,property_payload是上报的数据的内容。

属性是使用JSON格式进行描述的,由于上报的属性比较简单,并没有调用CJSON来组装JSON对

象,而是直接使用了snprintf对灯的状态进行了格式化。

请参考[物模型编程](https://help.aliyun.com/document_detail/96628.html)了解如何上报不同

数据类型的属性,以及一次上报多个属性时如何进行数据的格式化。

属性设置的处理

用户可以通过飞燕的APP或者云端控制台对属性进行设置,然后云端会将该设置命令发送给设备进行

处理,在示例代码中调用了函数user_property_set_event_handler()对属性设置进行处理,代码如

下所示:

文档版本:20200417 433

Page 446: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

在属性处理函数中,调用了CJSON的函数cJSON_GetObjectItem(root,"LightSwitch")来判断设置的

是否是灯的开关。注意,云端可能同时对多个属性进行设置,所以厂商在实现时需要遍历设备支持的

属性来确定用户设置的是哪个或者哪几个属性。

在示例代码中发现设置的是灯的状态时,仅仅是把设置的状态保存到设备的一个变量中,如上图的第

二个橙色圈选部分。在实际产品开发时,厂商应该去操作实际的硬件去进行灯的打开或者关闭。

在示例代码的最后,调用了user_post_property()将设备的最新状态上报云端。**设备厂商需要注意

的是**,当设备的属性发生了变化时,即使该变化是由于云端操作导致,也需要将设备的最新状态上

报到云端,否则在云端显示的仍然是上一次设备上报的属性值。

如果某个属性的操作非常耗时,或者可能导致阻塞,设备厂商可以创建一个线程去进行属性设置。

事件上报

示例代码中调用了函数()进行事件上报,函数体代码如下所示:

与属性上报不同,事件上报时需要指定事件ID(如上图中圈选的event_id),然后构造event的内

容(如上图中圈选的event_payload的构造语句),然后再调用IOT_Linkkit_TriggerEvent()上报事

件。

434 文档版本:20200417

Page 447: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

设备离线处理

示例代码对设备与云端连接断开事件注册了回调函数user_disconnected_event_handler,在示例

代码中仅仅只是进行了打印,厂商实际开发时需要按照自己产品的业务逻辑对该函数进行重写:

编译与调试

设备端

右键单击项目显示菜单,并点击其中的“Build Project”,如下图所示:

编译成功之后,在Eclipse之中将项目以“Local C/C++ Application”运行,下面是正确运行时的

console中的显示:

文档版本:20200417 435

Page 448: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中:“HAL_SSL_Establish successfully”表示设备与阿里云物联网平台的SSL连接已成功建立。

如果设备认证成功,将会有如下的输出:

灯连接到云端之后会将灯的状态上报云端,其中的“LightSwitch”为0表示灯的状态为“关”,如下

图所示:

> {

> "id": "1",

> "version": "1.0",

> "params": {

> "LightSwitch": 0

> },

> "method": "thing.event.property.post"

> }

然后每隔10秒,测试灯将会上报事件到云端,在console中的显示如下图所示:

> {

> "id": "2",

> "version": "1.0",

> "params": {

> "ErrorCode": 1

> },

> "method": "thing.event.Error.post"

> }

其中的ErrorCode为1表示温度超过80度的报警,为0表示告警消失

物联网平台端

开发者也可以在飞燕平台上查看设备的运行状态,如果设备已正常连接云端,那么云端显示如下图所

示:

436 文档版本:20200417

Page 449: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

其中可以看见设备的状态为“在线”,设备的“主灯开关”的状态为“关闭”

手机APP端

下载飞燕的调试APP

飞燕的APP名叫“云智能”,请访问自有品牌APP和公版APP页面,扫描该页面中提供的二维码进行

开发版app下载和安装,如下图橙色圈选的二维码:

文档版本:20200417 437

Page 450: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注:请不要扫描本页面中的“开发版”二维码,而是扫描“自有品牌APP和公版APP”页面中的二维

码。

使用调试APP绑定设备

确保设备已经正确的连接到了物联网平台,将手机连接到设备连接的同一个局域网,然后打开开发

版“云智能”APP,如果一切正常,手机的页面将会如下图所示:

438 文档版本:20200417

Page 451: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

注意:上图右上角的“+”号上方的红点表示手机APP发现了设备。

文档版本:20200417 439

Page 452: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

点击按钮“添加设备”,会打开设备添加页面,如果设备端代码工作正常,将会显示发现的设备的品

牌、名称、型号以及设备的DeviceName,如下图所示:

然后点击发现的设备右边的“+”号,设备添加成功之后将会出现设备的控制面板,如下图所示:

440 文档版本:20200417

Page 453: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

使用调试APP控制设备

用户可以在手机APP的面板上点击“开灯”将灯打开,也可以对已经打开的灯点击“关灯”进行关

闭。在设备端的串口上,当打开灯时会出现如下所示的信息:

1;32;40muser_property_set_event_handler.123: Property Set Received, Request: {"LightSwitch":1}> {> "id": "8",> "version": "1.0",> "params": {> "LightSwitch": 1> },> "method": "thing.event.property.post"> }

文档版本:20200417 441

Page 454: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

上面的打印信息中“LightSwitch”:1 表示设置灯的状态为开。

产品发布

当产品功能运行正常之后,厂商可以将产品在飞燕的控制台对产品进行发布,然后为每台需要生产的

设备申请激活码。

文档参考

• 设备Reset

当一个设备被一个用户绑定之后,在默认的绑定方式下另外一个用户是不能再对这个设备进行绑定和

控制的,必须原用户对设备进行解绑。有时候一个设备可能被转卖给另外一个客户之后,设备的拥有

者已经无法联系都设备曾经的拥有者,此时设备端调用IOT_DevReset_Report()可以让飞燕平台解除

这个设备与原拥有者的绑定关系。

因此,设备商需要在产品上设计一个reset按键,并当用户触按按键时调用IOT_DevReset_Report

()通知飞燕平台进行设备解绑,请参考“[设备Reset](https://help.aliyun.com/document_detail/

100494.html)”了解API调用详情。

• 设备固件升级

请参考“OTA开发”了解如何进行设备固件升级设计。

1.2.1.6 设备认证设备的身份认证分为一机一密以及一型一密两种:

• 一机一密: 在设备上烧写设备的ProductKey、DeviceName、DeviceSecret,然后适配相应的

HAL并调用SDK提供的连接云端的函数即可,这种方式要求对设备的产线工具进行一定的修改,需

要对每个设备烧写不同的DeviceName和DeviceSecret;

• 一型一密: 设备上烧写设备的ProductKey、ProductSecret,每个设备需要具备自己的唯一标识

并将该标识预先上传到阿里云IoT物联网平台,然后调用SDK提供的函数连接云端。这种方式每个

设备上烧写的信息是固定的ProductKey、ProductSecret

一机一密编程

设备厂商需要实现下面的三个HAL,用于让SDK获取设备三元组:

• HAL_GetProductKey

• HAL_GetDeviceName

• HAL_GetDeviceSecret

442 文档版本:20200417

Page 455: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

代码示例:

int main(int argc, char *argv[]){ void *pclient = NULL; int res = 0; int loop_cnt = 0; iotx_mqtt_param_t mqtt_params;

memset(&mqtt_params, 0x0, sizeof(mqtt_params)); mqtt_params.handle_event.h_fp = example_event_handle;

pclient = IOT_MQTT_Construct(&mqtt_params); if (NULL == pclient) { EXAMPLE_TRACE("MQTT construct failed"); return -1; } ...

++注:IOT_MQTT_Construct()将会调用上面提到的HAL_GetProductKey()等三个HAL函数去获取设

备的身份信息。++

一型一密编程

使用的流程示意

它工作时, IoT设备端和外界发生网络通信的交互过程是

简写说明

• PK: ProductKey, 设备品类标识字符串

• PS: ProductSecret, 设备品类密钥

• DN: DeviceName, 某台设备的标识字符串

• DS: DeviceSecret, 某台设备的设备密钥

文档版本:20200417 443

Page 456: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

流程简述: 1. 设备使用PK、PS和设备标识(DN)到阿里云物联网获取该设备对应的DS 2. 阿里云物

联网的动态注册Server将查找该设备的标识(DN)是否在该PK对应的设备列表,如果该设备在列表

中则将该设备的DS返回 3. 设备收到DS之后,将使用一机一密的方式计算MQTT连接参数以及签名 4.

设备使用计算出来的MQTT连接参数连接阿里云物联网平台

注1: 用户必须将获取的DeviceSecret持久化到设备, 以备后续使用. 若获取的DeviceSecret丢失可能

导致设备无法上线等严重后果, 云端服务器不会接受已激活设备重复的动态注册请求

注2: 使用一型一密功能, 用户必须对每个设备进行预注册, 即在阿里云物联网平台的控制台上传每个

设备的DeviceName,并且在控制台上打开对应产品的动态注册功能

例子程序讲解

一型一密功能的例子程序在 src/dynamic_register/examples/dynreg_example.c, 以下对其逐段

讲解

要使用一型一密功能, 要包含它的头文件 dynreg_api.h

#include <stdio.h>#include <string.h>#include "infra_types.h"#include "infra_defs.h"#include "dynreg_api.h"

444 文档版本:20200417

Page 457: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

准备输入参数 region 和出入参结构体 meta

iotx_http_region_types_t region = IOTX_HTTP_REGION_SHANGHAI;HAL_Printf("dynreg example\n");

memset(&meta,0,sizeof(iotx_dev_meta_info_t));HAL_GetProductKey(meta.product_key);HAL_GetProductSecret(meta.product_secret);HAL_GetDeviceName(meta.device_name);

以上例子程序用 IOTX_CLOUD_REGION_SHANGHAI 代表的华东二站点作为例子, 演示连接上海服务

器时候的情况, 另一个入参 meta 其实就是填入设备的 PK/PS/DN

调用一型一密的API获取 DeviceSecret

res = IOT_Dynamic_Register(region, &meta);if (res < 0) { HAL_Printf("IOT_Dynamic_Register failed\n"); return -1;}

HAL_Printf("\nDevice Secret: %s\n\n", meta.device_secret);

这个 IOT_Dynamic_Register() 接口就是一型一密功能点唯一提供的用户接口, 若执行成功, 在参数

meta 中将填上从服务器成功获取到的 DeviceSecret

其它

参考上面的图示

• 第1步和第2步对应用户接口: IOT_Dynamic_Register()

• 第3步对应用户接口: IOT_Sign_MQTT()

• 第4步对应用户接口: IOT_MQTT_Construct()

注:

• 因为当设备获取到DeviceSecret之后再次调用IOT_Dynamic_Register()将会返回失败,因此用户

编程时获取到DeviceSecret之后需要将其保存到Flash中;

• 用户的程序在调用IOT_Dynamic_Register()之前应该先调用HAL_GetDeviceSecret()查看设备是

否已经获取到了DeviceSecret,如果已经获取到,则无需再次去调用IOT_Dynamic_Register()

功能API接口

原型

int32_t IOT_Dynamic_Register(iotx_http_region_types_t region, iotx_dev_meta_info_t *meta);

文档版本:20200417 445

Page 458: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

根据输入参数中指定的站点区域, 以及productKey和productSecret, 去云端为deviceName指定的

设备去云端申请deviceSecret

参数说明

参数 数据类型 方向 说明

region iotx_http_region_types_t

输入 表示设备将要工作的区域, 例如美西/新加坡/日本/华东2站点等

meta iotx_dev_meta_info_t *

输入输出 输入的时候带入设备的 PK/PS/DN, 输出的时候返回从服务器取到的 DS

1.2.1.7 设备签名阿里云物联网平台支持使用MQTT协议作为IoT设备和平台之间的通信协议,MQTT Client在连接阿

里云物联网平台时MQTT的userName、password、clientID需要遵守阿里云IoT物联网平台的规

定,物联网平台将会使用这些参数验证设备的合法性。

功能点 dev_sign 提供的就是该签名字段的计算封装, 这个功能称为设备签名。

如上图所示

• 左边的是该模块的输入参数, 三元组和region分别表达设备身份和想要连接的站点所在区域(华东2

/日本/美西/新加坡...)

• 右边的是该模块的返回参数, hostname/port是连接服务器的域名和端口

446 文档版本:20200417

Page 459: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 另外3个则是IoT设备连接云平台时证明自己合法的身份认证信息, 统称为"设备签名信息"

图示正中间的是该模块提供的唯一一个用户接口API

使用场景说明

如果需要集成SDK的设备已支持MQTT Client,并且用户打算使用MQTT Topic直接与物联网平台进行

通信,并且不使用SDK的其它任何功能,可以调用设备签名API获取MQTT协议连接阿里云物联网平台

时需要设置的MQTT参数,然后使用用户自己的MQTT Client去连接阿里云物联网平台。

注:用户需要确保MQTT Client的KeepAlive机制正常运行。

例子程序讲解

设备签名的例子程序在 src/dev_sign/examples/dev_sign_example.c, 以下对其进行逐段讲解

要使用 dev_sign 功能, 需包含它的API头文件 dev_sign_api.h

#include "dev_sign_api.h"

从IoT控制台申请到一台新的IoT设备, 记录其三元组

#define EXAMPLE_PRODUCT_KEY "a1X2bEnP82z"#define EXAMPLE_PRODUCT_SECRET "7jluWm1zql7bt8qK"#define EXAMPLE_DEVICE_NAME "example1"#define EXAMPLE_DEVICE_SECRET "ga7XA6KdlEeiPXQPpRbAjOZXwG8ydgSe"

声明需要用户提供的底层接口

功能点 dev_sign 是零依赖的, 不需要用户做任何HAL的适配就可以使用. 这里声明了 HAL_Printf 仅

是因为例程可能需要输出字符

/* Implenment this HAL or using "printf" of your own system if you want to print something in example*/void HAL_Printf(const char *fmt, ...);

准备出入参结构体

int main(int argc, char *argv[]){ iotx_mqtt_region_types_t region = IOTX_CLOUD_REGION_SHANGHAI; iotx_dev_meta_info_t meta; iotx_sign_mqtt_t sign_mqtt;

memset(&meta,0,sizeof(iotx_dev_meta_info_t)); memcpy(meta.product_key,EXAMPLE_PRODUCT_KEY,strlen(EXAMPLE_PRODUCT_KEY)); memcpy(meta.product_secret,EXAMPLE_PRODUCT_SECRET,strlen(EXAMPLE_PRODUCT_SECRET)); memcpy(meta.device_name,EXAMPLE_DEVICE_NAME,strlen(EXAMPLE_DEVICE_NAME)); memcpy(meta.device_secret,EXAMPLE_DEVICE_SECRET,strlen(EXAMPLE_DEVICE_SECRET));

文档版本:20200417 447

Page 460: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

准备一个类型为 iotx_dev_meta_info_t 的结构体变量, 把需要计算签名的设备标识信息填入其中即

然后调用 dev_sign 功能点唯一的一个用户接口 IOT_Sign_MQTT(), 计算签名

if (IOT_Sign_MQTT(region,&meta,&sign_mqtt) < 0) { return -1; }

结果就在输出参数 sign_mqtt 中, 它是一个 iotx_sign_mqtt_t 类型的结构体变量

打印签名结果或者去连MQTT服务器

#if 0 /* Uncomment this if you want to show more information */ HAL_Printf("sign_mqtt.hostname: %s\n",sign_mqtt.hostname); HAL_Printf("sign_mqtt.port : %d\n",sign_mqtt.port); HAL_Printf("sign_mqtt.username: %s\n",sign_mqtt.username); HAL_Printf("sign_mqtt.password: %s\n",sign_mqtt.password); HAL_Printf("sign_mqtt.clientid: %s\n",sign_mqtt.clientid);#endif

为了减轻用户对接实现 HAL_Printf 的负担, IOT_Sign_MQTT() 在执行的过程中不会做任何打印动作,

如果想观察结果可打开上述注释

输出参数中的各个成员意义如下

成员名 含义

sign_mqtt.hostname 可以连接的MQTT服务器域名地址, 根据入参 region 自动计算

sign_mqtt.port 可以连接的MQTT服务器端口号, 根据标准MQTT协议一般是 1883 或者 443

sign_mqtt.username 连接MQTT服务器时将要使用的用户名

sign_mqtt.password 连接MQTT服务器时将要使用的密码, 和用户名一一对应

sign_mqtt.clientid 连接MQTT服务器时标识设备的自定义ID, 服务器对此不做校验, 鉴权通过 username 和 password 进行

功能API接口

原型

int32_t IOT_Sign_MQTT(iotx_mqtt_region_types_t region, iotx_dev_meta_info_t *meta, iotx_sign_mqtt_t *signout);

448 文档版本:20200417

Page 461: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

用于计算给定的IoT设备身份认证信息, 这些信息统称为它的"签名", 将在输出参数 signout 中返回

参数说明

参数 数据类型 方向 说明

region iotx_mqtt_region_types_t

输入 表示设备将要工作的区域, 例如美西/新加坡/日本/华东2站点等

meta iotx_dev_meta_info_t *

输入 存放设备的标识字符串, 包括 productKey, deviceName 等

signout iotx_sign_mqtt_t * 输出 存放计算好的签名信息, 包括MQTT服务器地址/端口, 连接时的用户名/密码等

需要对接的HAL接口

功能点 dev_sign 是零依赖的, 不需要用户做任何开发动作就可以使用, 所以不需要对接HAL接口

1.2.1.8 自定义MQTT Topic通信用户可以直接通过SDK提供的MQTT API与阿里云物联网平台通信,也即用户可以通过向指定

的topic发送消息的方式将数据发送到阿里云物联网平台,也可以通过订阅指定的topic从阿里云物联

网平台接收数据,这些topic都是用户自己定义的。

直接使用MQTT TOPIC与物联网平台通信的流程示意图如下:

文档版本:20200417 449

Page 462: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

说明:

• 通过调用 IOT_MQTT_Construct() 接口调用, 建立设备和云平台之间的长连接

- 这个接口是用来向云平台发起连接请求的, 其参数中需要的"签名信息"可以通过 dev_sign 功能

中的 IOT_Sign_MQTT() 获得

- 连接成功的话, 会返回一个 handle 参数, 这就是连接的句柄, 可用作之后所有MQTT网络接口的

入参

• 通过 IOT_MQTT_Subscribe() 接口调用, 可以向云平台表达设备将接收哪些Topic上的报文

• 然后进入业务主循环

- 通过 IOT_MQTT_Publish() 或 IOT_MQTT_Publish_Simple(), 可将消息上报到云端

- IOT_MQTT_Yield()用于接收云端下发的消息, 并调用用户在 IOT_MQTT_Subscribe() 时指定的

回调函数,用于对数据进行处理

例子程序讲解

MQTT上云的例子程序在 src/mqtt/examples/mqtt_example.c, 在"快速体验"一章中已对其进行过

逐段的讲解。请参考 快速体验 一章中的 "以MQTT Topic编程方式接入设备" 一节

功能API接口

函数名 说明

IOT_MQTT_CheckStateNormal

MQTT连接后, 调用此函数检查长连接是否正常

IOT_MQTT_Construct MQTT实例的构造函数, 入参为iotx_mqtt_param_t结构体, 连接MQTT服务器, 并返回被创建句柄

IOT_MQTT_Destroy MQTT实例的摧毁函数, 入参为 IOT_MQTT_Construct 创建的句柄

450 文档版本:20200417

Page 463: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

函数名 说明

IOT_MQTT_Publish MQTT会话阶段, 组织一个完整的MQTT Publish报文, 向服务端发送消息发布报文

IOT_MQTT_Publish_Simple MQTT会话阶段, 组织一个完整的MQTT Publish报文, 向服务端发送消息发布报文,参数中不含结构体等复杂数据类型

IOT_MQTT_Subscribe MQTT会话阶段, 组织一个完整的MQTT Subscribe报文, 向服务端发送订阅请求

IOT_MQTT_Subscribe_Sync MQTT会话阶段, 组织一个完整的MQTT Subscribe报文, 向服务端发送订阅请求,并等待应答

IOT_MQTT_Unsubscribe MQTT会话阶段, 组织一个完整的MQTT UnSubscribe报文, 向服务端发送取消订阅请求

IOT_MQTT_Yield MQTT会话阶段, MQTT主循环函数, 内含了心跳的维持, 服务器下行报文的收取等

需要实现的HAL接口

以下函数为可选实现, 如果希望SDK提供MQTT通道功能, 则需要用户对接

函数名 说明

HAL_UptimeMs 返回设备加电以来到当前时间点过去的毫秒数

HAL_SleepMs 按照入参指定的毫秒数睡眠相应时间

HAL_SSL_Destroy 销毁一个TLS连接, 用于MQTT功能, 加密连接的情况

HAL_SSL_Establish 建立一个TLS连接, 用于MQTT功能, 加密连接的情况

HAL_SSL_Read 从一个TLS连接中读数据, 用于MQTT功能, 加密连接的情况

HAL_SSL_Write 向一个TLS连接中写数据, 用于MQTT功能, 加密连接的情况

HAL_TCP_Destroy 销毁一个TLS连接, 用于MQTT功能

HAL_TCP_Establish 建立一个TCP连接, 包含了域名解析的动作和TCP连接的建立

HAL_TCP_Read 在指定时间内, 从TCP连接读取流数据, 并返回读到的字节数

HAL_TCP_Write 在指定时间内, 向TCP连接发送流数据, 并返回发送的字节数

注: SDK提供的用户API接口都列在 src/mqtt/mqtt_api.h, 可能需要对接的HAL函数都列在 src/mqtt

/mqtt_wrapper.h, 以代码为准

文档版本:20200417 451

Page 464: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.9 物模型编程物模型管理功能是指使用 属性/事件/服务 的方式对产品支持的能力进行描述,在设备开发时也需要

以物模型的方式进行编程。

下面的讲解中使用了示例代码./src/dev_model/examples/linkkit_example_solo.c。

注意:

1. 在Linux环境下,用户可通过修改wrappers/os/ubuntu/HAL_OS_linux.c文件中的默认三元组

来使用自己在云端控制台创建的设备的身份信息。

2. 我们在src/dev_model/examples目录下提供了名为model_for_example.json的物模型描述文

件,用户可以用自己产品的productkey替换掉该文件中的productKey值后,将该物模型文件导

入到物联网平台上的产品定义中,这样用户可以快速的参照示例代码来体验基于物模型的编程方

式。

设备属性

• 属性上报说明

用户可以调用IOT_Linkkit_Report()函数来上报属性,属性上报时需要按照云端定义

的属性格式使用JSON编码后进行上报。示例中函数user_post_property展示了如何使

用IOT_Linkkit_Report进行属性上报(对于异常情况的上报,详见example)。

void user_post_property(void){ static int cnt = 0; int res = 0;

char property_payload[30] = {0}; HAL_Snprintf(property_payload, sizeof(property_payload), "{\"Counter\": %d}", cnt++);

res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY, (unsigned char *)property_payload, strlen(property_payload));

EXAMPLE_TRACE("Post Property Message ID: %d", res);}

注意:

property_payload = “{\”Counter\”:1}” 即是将属性编码为JSON对象。

当上报属性或者事件时需要云端应答时,通过IOT_Ioctl对IOTX_IOCTL_RECV_EVENT_REPLY选项

进行设置。

452 文档版本:20200417

Page 465: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 属性设置说明

示例代码在回调函数user_property_set_event_handler中获取云端设置的属性值,并原样将收

到的数据发回给云端,这样可以更新在云端的设备属性值,用户可在此处对收到的属性值进行处

理。

说明:

该回调函数是在example初始化时使用IOT_RegisterCallback注册的ITE_SERVICE_REQUST事件

对应的回调函数。

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(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY, (unsigned char *)request, request_len); EXAMPLE_TRACE("Post Property Message ID: %d", res);

return 0;}

设备服务

在设备端示例程序中,当收到服务调用请求时,会进入如下回调函数,以下代码使用了cJSON来解析

服务请求的参数值。

static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len, const char *request, const int request_len, char **response, int *response_len){ int add_result = 0; cJSON *root = NULL, *item_number_a = NULL, *item_number_b = NULL; const char *response_fmt = "{\"Result\": %d}";

EXAMPLE_TRACE("Service Request Received, Service ID: %.*s, Payload: %s", serviceid_len, serviceid, request);

/* Parse Root */ root = cJSON_Parse(request); if (root == NULL || !cJSON_IsObject(root)) { EXAMPLE_TRACE("JSON Parse Error"); return -1; }

if (strlen("Operation_Service") == serviceid_len && memcmp("Operation_Service", serviceid, serviceid_len) == 0) { /* Parse NumberA */ item_number_a = cJSON_GetObjectItem(root, "NumberA"); if (item_number_a == NULL || !cJSON_IsNumber(item_number_a)) { cJSON_Delete(root); return -1; } EXAMPLE_TRACE("NumberA = %d", item_number_a->valueint);

文档版本:20200417 453

Page 466: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

/* Parse NumberB */ item_number_b = cJSON_GetObjectItem(root, "NumberB"); if (item_number_b == NULL || !cJSON_IsNumber(item_number_b)) { cJSON_Delete(root); return -1; } EXAMPLE_TRACE("NumberB = %d", item_number_b->valueint);

add_result = item_number_a->valueint + item_number_b->valueint;

/* Send Service Response To Cloud */ *response_len = strlen(response_fmt) + 10 + 1; *response = (char *)HAL_Malloc(*response_len); if (*response == NULL) { EXAMPLE_TRACE("Memory Not Enough"); return -1; } memset(*response, 0, *response_len); HAL_Snprintf(*response, *response_len, response_fmt, add_result); *response_len = strlen(*response); }

cJSON_Delete(root); return 0;}

设备事件

示例中使用IOT_Linkkit_TriggerEvent上报事件。其中展示了如何使用IOT_Linkkit_Report进行事件

上报(对于异常情况的上报,详见example)。

void user_post_event(void){ int res = 0; char *event_id = "HardwareError"; char *event_payload = "{\"ErrorCode\": 0}";

res = IOT_Linkkit_TriggerEvent(EXAMPLE_MASTER_DEVID, event_id, strlen(event_id), event_payload, strlen(event_payload)); EXAMPLE_TRACE("Post Event Message ID: %d", res);}

关于上报消息的格式说明及示例

上报属性时,属性ID和值以JSON格式的形式放在IOT_Linkkit_Report()的payload中,不同数据类

型以及多个属性的格式示例如下。

/* 整型数据 */char *payload = "{\"Brightness\":50}";

/* 浮点型数据上报 */char *payload = "{\"Temperature\":11.11}";

/* 枚举型数据上报 */char *payload = "{\"WorkMode\":2}";

/* 布尔型数据上报, 在物模型定义中, 布尔型为整型, 取值为0或1, 与JSON格式的整型不同 */ *payload = "{\"LightSwitch\":1}";

454 文档版本:20200417

Page 467: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

/* 字符串数据上报 */char *payload = "{\"Description\":\"Amazing Example\"}";

/* 时间型数据上报, 在物模型定义中, 时间型为字符串 */char *payload = "{\"Timestamp\":\"1252512000\"}";

/* 复合类型属性上报, 在物模型定义中, 符合类型属性为JSON对象 */char *payload = "{\"RGBColor:{\"Red\":11,\"Green\":22,\"Blue\":33}\"}";

/* 多属性上报, 如果需要上报以上各种数据类型的所有属性, 将它们放在一个JSON对象中即可 */char *payload = "{\"Brightness\":50,\"Temperature\":11.11,\"WorkMode\":2,\"LightSwitch\":1,\"Description\":\"Amazing Example\",\"Timestamp\":\"1252512000\",\"RGBColor:{\"Red\":11,\"Green\":22,\"Blue\":33}\"}";

/* 属性payload准备好以后, 就可以使用如下接口进行上报了 */IOT_Linkkit_Report(devid, ITM_MSG_POST_PROPERTY, payload, strlen(payload));

上报事件时,与上报属性的区别是,事件ID需要单独拿出来,放

在IOT_Linkkit_TriggerEvent()的eventid中,而事件的上报内容,也就是物模型定义中事件的输出

参数,则使用与上报属性相同的格式进行上报,示例如下。

/* 事件ID为Error, 其输出参数ID为ErrorCode, 数据类型为枚举型 */char *eventid = "Error";char *payload = "{\"ErrorCode\":0}";

/* 事件ID为HeartbeatNotification, 其输出参数有2个. 第一个是布尔型参数ParkingState, 第二个是浮点型参数VoltageValue */char *eventid = "HeartbeatNotification";char *payload = "{\"ParkingState\":1,\"VoltageValue\":3.0}";

/* 事件payload准备好以后, 就可以使用如下接口进行上报了 */IOT_Linkkit_TriggerEvent(devid, event_id, strlen(event_id), payload, strlen(payload));

/* 从上面的示例可以看出, 当事件的输出参数有多个时, payload的格式与多属性上报是相同的 */

基于MQTT Topic进行数据收发

注意:

虽然物模型编程的API并未返回MQTT编程接口IOT_MQTT_XXX()所需要的pClient参数,但基

于MQTT Topic进行数据收发仍可和物模型编程混用。

文档版本:20200417 455

Page 468: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 所有MQTT数据收发的接口,第1个参数都可接受参数 0 作为输入,表示 “使用当前唯一

的MQTT通道进行数据收发等操作”,包括:

- IOT_MQTT_Construct

- IOT_MQTT_Destroy

- IOT_MQTT_Yield

- IOT_MQTT_CheckStateNormal

- IOT_MQTT_Subscribe

- IOT_MQTT_Unsubscribe

- IOT_MQTT_Publish

- IOT_MQTT_Subscribe_Sync

- IOT_MQTT_Publish_Simple

• 例如要在使用物模型编程API的程序代码段落中表示对某个Topic进行订阅,可以用

IOT_MQTT_Subscribe(0, topic_request, IOTX_MQTT_QOS0, topic_callback, topic_context);

• 例如要在使用物模型编程API的程序代码段落中表示在某个Topic进行发布(数据上报),可以用

IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, payload_len);

与物模型功能相关的API列表

函数名 说明

IOT_Linkkit_Open 创建本地资源,在进行网络报文交互之前,必须先调用此接口,得到一个会话的句柄

IOT_Linkkit_Connect 对主设备/网关来说,将会建立设备与云端的通信。对于子设备来说,将向云端注册该子设备(若需要),并添加主子设备拓扑关系

IOT_Linkkit_Yield 若SDK占有独立线程,该函数只将接收到的网络报文分发到用户的回调函数中,否则表示将CPU交给SDK让其接收网络报文并将消息分发到用户的回调函数中

IOT_Linkkit_Close 若入参中的会话句柄为主设备/网关,则关闭网络连接并释放SDK为该会话所占用的所有资源

IOT_Linkkit_TriggerEvent 向云端发送事件报文、错误码、异常告警等

IOT_Linkkit_Report 向云端发送没有云端业务数据下发的上行报文,包括属性值/设备标签/二进制透传数据/子设备管理等各种报文

456 文档版本:20200417

Page 469: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

函数名 说明

IOT_Linkkit_Query 向云端发送存在云端业务数据下发的查询报文,包括OTA状态查询/OTA固件下载/子设备拓扑查询/NTP时间查询等各种报文

函数名 说明

IOT_RegisterCallback 对SDK注册事件回调函数,如云端连接成功/失败,有属性设置/服务请求到达,子设备管理报文答复等

IOT_Ioctl 对SDK进行各种参数运行时设置和获取,以及运行状态的信息获取等,实参可以是任何数据类型

1.2.1.10 设备影子背景信息

设备影子是指通过特别的Topic在云端构建一个设备的影子,设备同步状态至云端。当设备离线

时,云端仍可以快速通过影子获取到设备的状态。

说明:

对于使用物模型在物联网平台进行定义的产品,其属性会保存在云端,无需使用设备影子来告知物

联网平台保存其数据。

操作步骤

1. 设备C-SDK提供接口IOT_Shadow_Construct ,创建设备影子。函数声明如下:

/*** @brief Construct the Device Shadow.* This function initialize the data structures, establish MQTT connection.* and subscribe the topic: "/shadow/get/${YourProduct_key}/${YourDevice_name}".** @param [in] pparam: The specific initial parameter.* @retval NULL : Construct shadow failed.* @retval NOT_NULL : Construct success.* @see None.*/void *IOT_Shadow_Construct(iotx_shadow_para_pt pparam);

2. 使用IOT_Shadow_RegisterAttribute接口,注册设备影子的属性。函数声明如下:

/*** @brief Create a data type registered to the server.** @param [in] handle: The handle of device shaodw.* @param [in] pattr: The parameter which registered to the server.* @retval SUCCESS_RETURN : Success.* @retval other : See iotx_err_t.

文档版本:20200417 457

Page 470: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

* @see None.*/iotx_err_t IOT_Shadow_RegisterAttribute(void *handle, iotx_shadow_attr_pt pattr);

3. 设备影子在每次开机时,设备C-SDK提供IOT_Shadow_Pull接口,从云端同步设备状态。函数声

明如下:

/*** @brief Synchronize device shadow data from cloud.* It is a synchronous interface.* @param [in] handle: The handle of device shaodw.* @retval SUCCESS_RETURN : Success.* @retval other : See iotx_err_t.* @see None.*/iotx_err_t IOT_Shadow_Pull(void *handle);

4. 当设备端状态发生变化时,设备C-SDK提供接

口IOT_Shadow_PushFormat_Init、IOT_Shadow_PushFormat_Add和IOT_Shadow_PushFormat_Finalize接

口更新状态,通过接口IOT_Shadow_Push将状态同步到云端。函数声明如下:

/*** @brief Start a process the structure of the data type format.** @param [in] handle: The handle of device shaodw.* @param [out] pformat: The format struct of device shadow.* @param [in] buf: The buf which store device shadow.* @param [in] size: Maximum length of device shadow attribute.* @retval SUCCESS_RETURN : Success.* @retval other : See iotx_err_t.* @see None.*/iotx_err_t IOT_Shadow_PushFormat_Init( void *handle, format_data_pt pformat, char *buf, uint16_t size);

/*** @brief Format the attribute name and value for update.** @param [in] handle: The handle of device shaodw.* @param [in] pformat: The format struct of device shadow.* @param [in] pattr: To have created the data type of the format in the add member attributes.* @retval SUCCESS_RETURN : Success.* @retval other : See iotx_err_t.* @see None.*/iotx_err_t IOT_Shadow_PushFormat_Add( void *handle, format_data_pt pformat, iotx_shadow_attr_pt pattr);

/*** @brief Complete a process the structure of the data type format.

458 文档版本:20200417

Page 471: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

** @param [in] handle: The handle of device shaodw.* @param [in] pformat: The format struct of device shadow.* @retval SUCCESS_RETURN : Success.* @retval other : See iotx_err_t.* @see None.*/iotx_err_t IOT_Shadow_PushFormat_Finalize(void *handle, format_data_pt pformat);

5. 当设备需要与云端断开连接时,设备C-SDK提供接

口IOT_Shadow_DeleteAttribute和IOT_Shadow_Destroy,删除云端创建的属性并释放设备影

子。函数声明如下:

/*** @brief Deconstruct the specific device shadow.** @param [in] handle: The handle of device shaodw.* @retval SUCCESS_RETURN : Success.* @retval other : See iotx_err_t.* @see None.*/iotx_err_t IOT_Shadow_Destroy(void *handle);

1.2.1.11 远程配置服务端可以向设备端主动下推远程配置信息, 设备端也可以向服务端主动查询远程配置信息,设备离

线期间服务端如果发布过远程配置信息, 设备端可以通过后者这种方式来获取到更改后的配置信息。

更多COTA相关功能说明可查看远程配置

在与阿里云物联网平台建立连接之前,注册对事件ITE_COTA的处理函数,当云端修改配置之

后,SDK将会调用用户注册的处理函数,处理函数需要使用IOT_Linkkit_Query来请求COTA数据。

1. 定义COTA事件回调函数及获取配置数据

下面是回调函数的示例代码,其中使用了IOT_Linkkit_Query来请求COTA数据:

static int user_cota_event_handler(int type, const char *config_id, int config_size, const char *get_type, const char *sign, const char *sign_method, const char *url){ char buffer[128] = {0}; int buffer_length = 128; user_example_ctx_t *user_example_ctx = user_example_get_ctx();

if (type == 0) { EXAMPLE_TRACE("New Config ID: %s", config_id); EXAMPLE_TRACE("New Config Size: %d", config_size); EXAMPLE_TRACE("New Config Type: %s", get_type); EXAMPLE_TRACE("New Config Sign: %s", sign); EXAMPLE_TRACE("New Config Sign Method: %s", sign_method); EXAMPLE_TRACE("New Config URL: %s", url);

文档版本:20200417 459

Page 472: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

IOT_Linkkit_Query(user_example_ctx->master_devid, ITM_MSG_QUERY_COTA_DATA, (unsigned char *)buffer, buffer_length); }

return 0;}

2. 注册COTA事件回调函数

下面是示例代码:

int main(int argc, char **argv){ char buffer[128] = {0}; int buffer_length = 128; ...

IOT_RegisterCallback(ITE_COTA, user_cota_event_handler);

...

memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t)); memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME)); memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));

...

res = IOT_Linkkit_Connect(user_example_ctx->master_devid); if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1; }

...}

设备端向服务端主动查询远程配置信息

对于设备端主动请求COTA的情况,用户仍然需要注册COTA事件的回调函数(相关代码见上面的描

述)。当设备连接到阿里云物联网平台后,调用IOT_Linkkit_Query来请求云端下发COTA数据。

下面是示例代码:

int main(int argc, char **argv){ ...

user_example_ctx->master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info); if (user_example_ctx->master_devid < 0) {

460 文档版本:20200417

Page 473: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n"); return -1; } res = IOT_Linkkit_Connect(user_example_ctx->master_devid); if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1; }

/*告知云端推送COTA数据*/ IOT_Linkkit_Query(user_example_ctx->master_devid, ITM_MSG_REQUEST_COTA, NULL, 0);

...}

远程配置功能API

函数名 说明

IOT_Linkkit_Open 创建本地资源, 在进行网络报文交互之前, 必须先调用此接口, 得到一个会话的句柄

IOT_Linkkit_Connect 对主设备/网关来说, 将会建立设备与云端的通信. 对于子设备来说, 将向云端注册该子设备(若需要), 并添加主子设备拓扑关系

IOT_Linkkit_Yield 若SDK占有独立线程, 该函数只将接收到的网络报文分发到用户的回调函数中, 否则表示将CPU交给SDK让其接收网络报文并将消息分发到用户的回调函数中

IOT_Linkkit_Close 若入参中的会话句柄为主设备/网关, 则关闭网络连接并释放SDK为该会话所占用的所有资源

IOT_Linkkit_Query 向云端发送存在云端业务数据下发的查询报文,包括OTA状态查询/OTA固件下载/子设备拓扑查询/NTP时间查询等各种报文

需要实现的HAL

1.2.1.12 标签上报设备标签信息更新的消息时, 标签信息放在成对的一组或多组attrKey和attrValue中. attrKey的

定义支持大小写字母及数字, 但不能以数字开头, 长度为2~32个字节, payload为JSON数组类型, 可包

含多对{"attrKey":"","attrValue":""}, 示例如下:

文档版本:20200417 461

Page 474: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

设备标签是用于展示如设备信息, 如厂商/设备型号的静态扩展信

息, 以键值对的形式存储在云端

/* 设备标签有两组, 第一组attrKey为abc, attrValue为Hello,World. 第二组attrKey为def, attrValue为Hello,Aliyun */char *payload = "[{\"attrKey\":\"abc\",\"attrValue\":\"Hello,World\"},{\"attrKey\":\"def\",\"attrValue\":\"Hello,Aliyun\"}]";

/* 设备标签payload准备好以后, 就可以使用如下接口进行上报了 */IOT_Linkkit_Report(devid, ITM_MSG_DEVICEINFO_UPDATE, (unsigned char *)payload, strlen(payload));

向云端发送删除设备标签的消息

上报设备标签信息删除的消息时, 将标签信息的attrKey放在一个或多个attrKey中

/* 设备标签attrKey有两个, 第一个attrKey为abc. 第二个attrKey为def */char *payload = "[{\"attrKey\":\"abc\"},{\"attrKey\":\"def\"}]";

/* 设备标签payload准备好以后, 就可以使用如下接口进行上报了 */IOT_Linkkit_Report(devid, ITM_MSG_DEVICEINFO_DELETE, (unsigned char *)payload, strlen(payload));

1.2.1.13 设备OTA开发OTA(Over-the-Air Technology)即空中下载技术,物联网平台支持通过OTA方式进行设备固件升

级。

背景信息

基于MQTT协议下固件升级流程如下。

462 文档版本:20200417

Page 475: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

OTA例程讲解

• 过OTA的API可以实现设备端固件下载。但是如何存储/使用下载到的固件,需要用户实现。

• 存储固件是指将下载到的固件存储到FLASH等介质上。

• 使用固件,包括加载新下载的固件,需要用户根据业务的具体需求(例如需要用户单击升级按

钮)来实现。

说明:

OTA整体流程请见OTA服务。

下面用两个例子分别说明如何用基础版接口和高级版接口来实现OTA功能。

用基础版接口实现的OTA例程

现对照 src/ota/examples/ota_example_mqtt.c 例程分步骤讲解如何使用基础版的接口实现OTA

的功能。

1. OTA业务建立前的准备:导入设备三元组,初始化连接信息。

int main(int argc, char *argv[]) { ... /**< get device info*/ HAL_SetProductKey(PRODUCT_KEY); HAL_SetDeviceName(DEVICE_NAME); HAL_SetDeviceSecret(DEVICE_SECRET); /**< end*/ _ota_mqtt_client()

文档版本:20200417 463

Page 476: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

2. 在_ota_mqtt_client函数完成建连和OTA的主要配置逻辑。

/* Device AUTH */ if (0 != IOT_SetupConnInfo(g_product_key, g_device_name, g_device_secret, (void **)&pconn_info)) { EXAMPLE_TRACE("AUTH request failed!"); rc = -1; goto do_exit; }

/* Initialize MQTT parameter */ memset(&mqtt_params, 0x0, sizeof(mqtt_params)); mqtt_params.port = pconn_info->port; mqtt_params.host = pconn_info->host_name; mqtt_params.client_id = pconn_info->client_id; mqtt_params.username = pconn_info->username; mqtt_params.password = pconn_info->password; mqtt_params.pub_key = pconn_info->pub_key;

mqtt_params.request_timeout_ms = 2000; mqtt_params.clean_session = 0; mqtt_params.keepalive_interval_ms = 60000; mqtt_params.read_buf_size = OTA_MQTT_MSGLEN; mqtt_params.write_buf_size = OTA_MQTT_MSGLEN;

mqtt_params.handle_event.h_fp = event_handle; mqtt_params.handle_event.pcontext = NULL;

/* Construct a MQTT client with specify parameter */ pclient = IOT_MQTT_Construct(&mqtt_params); if (NULL == pclient) { EXAMPLE_TRACE("MQTT construct failed"); rc = -1; goto do_exit; }

3. 在_ota_mqtt_client函数进行OTA有关的初始化工作(主要是订阅跟这个设备有关的固件升级信

息)。

h_ota = IOT_OTA_Init(PRODUCT_KEY, DEVICE_NAME, pclient); if (NULL == h_ota) { rc = -1; EXAMPLE_TRACE("initialize OTA failed"); goto do_exit; }

4. 建立一个循环,一直去尝试接收OTA升级的消息。

int ota_over = 0; do { uint32_t firmware_valid; EXAMPLE_TRACE("wait ota upgrade command....");

/* 接收MQTT消息 */ IOT_MQTT_Yield(pclient, 200);

/* 判断接收到的消息中是否有固件升级的消息 */ if (IOT_OTA_IsFetching(h_ota)) { /* 下载OTA内容, 上报下载进度,见章节 "5. 下载OTA内容, 上报下载进度" */

464 文档版本:20200417

Page 477: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

/* 校验固件的md5, 见章节 "6. 校验md5的值" */ }

} while (!ota_over);

需要到服务端推送一个固件升级事件下去,IOT_OTA_IsFetching返回才能结果为1,才能走入固

件升级的逻辑。推送固件升级事件的具体步骤如下。

a) 到IoT控制台的 OTA服务页面,单击新增固件。

b) 单击创建固件,验证固件。

c) 单击这个新增固件的批量升级按钮,从中选择设备所属产品为examples/ota/ota_mqtt-

example.c中三元组对应的产品。

d) 待升级版本号点开下拉框选当前版本号,升级范围选定向升级,再从设备范围中选当前的三元

组对应的设备,单击确定即可。

5. 下载OTA内容,上报下载进度。

do {

/* 下载OTA固件 */ len = IOT_OTA_FetchYield(h_ota, buf_ota, OTA_BUF_LEN, 1); if (len > 0) { if (1 != fwrite(buf_ota, len, 1, fp)) { EXAMPLE_TRACE("write data to file failed"); rc = -1; break; } } else {

/* 上报已下载进度 */ IOT_OTA_ReportProgress(h_ota, IOT_OTAP_FETCH_FAILED, NULL); EXAMPLE_TRACE("ota fetch fail"); }

/* get OTA information */ /* 获取已下载到的数据量, 文件总大小, md5信息, 版本号等信息 */ IOT_OTA_Ioctl(h_ota, IOT_OTAG_FETCHED_SIZE, &size_downloaded, 4); IOT_OTA_Ioctl(h_ota, IOT_OTAG_FILE_SIZE, &size_file, 4); IOT_OTA_Ioctl(h_ota, IOT_OTAG_MD5SUM, md5sum, 33); IOT_OTA_Ioctl(h_ota, IOT_OTAG_VERSION, version, 128);

last_percent = percent; percent = (size_downloaded * 100) / size_file; if (percent - last_percent > 0) {

/* 上报已下载进度 */ IOT_OTA_ReportProgress(h_ota, percent, NULL); IOT_OTA_ReportProgress(h_ota, percent, "hello"); } IOT_MQTT_Yield(pclient, 100);

/* 判断下载是否结束 */ } while (!IOT_OTA_IsFetchFinish(h_ota));

6. 校验md5的值。

IOT_OTA_Ioctl(h_ota, IOT_OTAG_CHECK_FIRMWARE, &firmware_valid, 4); if (0 == firmware_valid) {

文档版本:20200417 465

Page 478: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

EXAMPLE_TRACE("The firmware is invalid"); } else { EXAMPLE_TRACE("The firmware is valid"); }

ota_over = 1;

7. 用户通过IOT_OTA_Deinit释放所有资源。

if (NULL != h_ota) { IOT_OTA_Deinit(h_ota); }

if (NULL != pclient) { IOT_MQTT_Destroy(&pclient); }

if (NULL != msg_buf) { HAL_Free(msg_buf); }

if (NULL != msg_readbuf) { HAL_Free(msg_readbuf); }

if (NULL != fp) { fclose(fp); }

return rc;

8. 固件的存储。

在_ota_mqtt_client函数中通过下述方式打开,写入和关闭一个文件。

fp = fopen("ota.bin", "wb+")...if (1 != fwrite(buf_ota, len, 1, fp)) { EXAMPLE_TRACE("write data to file failed"); rc = -1; break;}...if (NULL != fp) { fclose(fp);}

用高级版接口实现的OTA例程

现对照src/dev_model/examples/linkkit_example_solo.c分步骤讲解如何使用高级版的接口实

现OTA的功能。

1. 初始化主设备,注册FOTA的回调函数,建立与云端的连接。

int res = 0;int domain_type = 0, dynamic_register = 0, post_reply_need = 0;iotx_linkkit_dev_meta_info_t master_meta_info;

memset(&g_user_example_ctx, 0, sizeof(user_example_ctx_t));

466 文档版本:20200417

Page 479: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t));memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY));memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET));memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME));memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));

/* Register Callback */......IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler);

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);

/* post reply doesn't need */post_reply_need = 1;IOT_Ioctl(IOTX_IOCTL_RECV_EVENT_REPLY, (void *)&post_reply_need);

/* Create Master Device Resources */g_user_example_ctx.master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);if (g_user_example_ctx.master_devid < 0) { EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n"); return -1;}

/* Start Connect Aliyun Server */res = IOT_Linkkit_Connect(g_user_example_ctx.master_devid);if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1;}

2. 实现上述代码中的回调函数user_fota_event_handler。

该回调函数在如下两种情况下会被触发:

• 直接收到云端下发的新固件通知时。

• 由设备端主动发起新固件查询,云端返回新固件通知时。

在收到新固件通知后,可调用IOT_Linkkit_Query进行固件下载。

int user_fota_event_handler(int type, const char *version){ char buffer[128] = {0}; int buffer_length = 128;

/* 0 - new firmware exist, query the new firmware */ if (type == 0) { EXAMPLE_TRACE("New Firmware Version: %s", version);

IOT_Linkkit_Query(EXAMPLE_MASTER_DEVID, ITM_MSG_QUERY_FOTA_DATA, (unsigned char *)buffer, buffer_length); }

return 0;

文档版本:20200417 467

Page 480: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

3. 固件的存储。

用户需要实现如下3个HAL接口来实现固件的存储。

/* SDK在开始下载固件之前进行调用 */void HAL_Firmware_Persistence_Start(void);

/* SDK在接收到固件数据时进行调用 */int HAL_Firmware_Persistence_Write(char *buffer, uint32_t length);

/* SDK在固件下载结束时进行调用 */int HAL_Firmware_Persistence_Stop(void);

4. 用户主动发起新固件查询。

IOT_Linkkit_Query(user_example_ctx->master_devid, ITM_MSG_REQUEST_FOTA_IMAGE, (unsigned char *)("app-1.0.0-20180101.1001"), 30);

OTA功能API

• 用基础版接口实现OTA功能涉及的API。

函数名 说明

IOT_OTA_Init OTA实例的构造函数,创建一个OTA会话的句柄并返回。

IOT_OTA_Deinit OTA实例的摧毁函数,销毁所有相关的数据结构。

IOT_OTA_Ioctl OTA实例的输入输出函数,根据不同的命令字可以设置OTA会话的属性,或者获取OTA会话的状态。

IOT_OTA_GetLastError OTA会话阶段,若某个IOT_OTA_XXX()函数返回错误,调用此接口可获得最近一次的详细错误码。

IOT_OTA_ReportVersion OTA会话阶段,向服务端汇报当前的固件版本号。

IOT_OTA_FetchYield OTA下载阶段,在指定的timeout时间内,从固件服务器下载一段固件内容,保存在入参buffer中。

IOT_OTA_IsFetchFinish OTA下载阶段,判断迭代调用IOT_OTA_FetchYield是否已经下载完所有的固件内容。

IOT_OTA_IsFetching OTA下载阶段,判断固件下载是否仍在进行中,尚未完成全部固件内容的下载。

IOT_OTA_ReportProgress 可选API,OTA下载阶段,调用此函数向服务端汇报已经下载了全部固件内容的百分之多少。

• 用高级版接口实现OTA功能涉及的API。

函数名 说明

IOT_Linkkit_Open 创建本地资源,在进行网络报文交互之前,必须先调用此接口,得到一个会话的句柄。

468 文档版本:20200417

Page 481: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

函数名 说明

IOT_Linkkit_Connect 对主设备/网关来说,将会建立设备与云端的通信。对于子设备来说,将向云端注册该子设备(若需要),并添加主子设备拓扑关系。

IOT_Linkkit_Yield 若SDK占有独立线程,该函数只将接收到的网络报文分发到用户的回调函数中,否则表示将CPU交给SDK让其接收网络报文并将消息分发到用户的回调函数中。

IOT_Linkkit_Close 若入参中的会话句柄为主设备/网关,则关闭网络连接并释放SDK为该会话所占用的所有资源。

IOT_Linkkit_Query 向云端发送存在云端业务数据下发的查询报文,包括OTA状态查询/OTA固件下载/子设备拓扑查询/NTP时间查询等各种报文。

IOT_RegisterCallback 对SDK注册事件回调函数,如云端连接成功/失败,有属性设置/服务请求到达,子设备管理报文答复等。

需要实现的HAL

• 用基础版接口实现OTA功能需要实现的API。

无。

• 用高级版接口实现OTA功能需要实现的API。

函数名 说明

HAL_Firmware_Persistence_Start

固件持久化功能开始

HAL_Firmware_Persistence_Write

固件持久化写入固件

HAL_Firmware_Persistence_Stop

固件持久化功能结束

1.2.1.14 子设备管理本节内容将结合src/dev_model/examples/linkkit_example_gateway.c为例讲解网关产品的编程

方法。

背景信息

名词 说明

网关 能够直接连接物联网平台的设备,且具有子设备管理功能,能够代理子设备连接云端。

子设备 本质上也是设备。子设备不能直接连接物联网平台,只能通过网关连接。

文档版本:20200417 469

Page 482: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

名词 说明

设备ID Device ID,也就是设备句柄,在网关场景中用于标识一个具体的设备,调用IOT_Linkkit_Open时返回。

拓扑关系 子设备和网关的关联关系为拓扑关系,子设备与网关建立拓扑关系后,便可以复用网关的物理通道进行数据通信。

子设备动态注册 子设备在注册时只需将productKey和deviceName上报给网关,网关代替子设备向云端发起身份认证并获取云端返回的deviceSecret用之后的上线操作。

管理子设备

1. 网关与云端建连。

网关的建连过程与单品直连设备的建连过程完全一致。

a) 调用IOT_RegisterCallback注册必要的回调处理函数,如连接事件处理,设备连云初始

化完成处理,属性设置事件处理等回调函数。子设备和网关共用一组回调处理函数,以参

数DeviceID来区分不同的设备。

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);

b) 调用IOT_Ioctl进行必要的配置,如选择服务器站点,选择是否使用一型一密等等。

/* Choose Login Server */ int domain_type = IOTX_CLOUD_REGION_SHANGHAI; IOT_Ioctl(IOTX_IOCTL_SET_DOMAIN, (void *)&domain_type);

/* Choose Login Method */ int dynamic_register = 0; IOT_Ioctl(IOTX_IOCTL_SET_DYNAMIC_REGISTER, (void *)&dynamic_register);

c) 使用IOTX_LINKKIT_DEV_TYPE_MASTER参数调用IOT_Linkkit_Open初始化主设备资源。

iotx_linkkit_dev_meta_info_t master_meta_info;

memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t)); memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET));

470 文档版本:20200417

Page 483: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME)); memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));

/* Create Master Device Resources */ user_example_ctx->master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info); if (user_example_ctx->master_devid < 0) { EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n"); return -1; }

d) 同样使用IOTX_LINKKIT_DEV_TYPE_MASTER参数调用IOT_Linkkit_Connect与云端建立连接。

/* Start Connect Aliyun Server */ res = IOT_Linkkit_Connect(user_example_ctx->master_devid); if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1; }

e) 在ITE_INITIALIZE_COMPLETED事件处理函数中确认网关连云初始化完成后,便可以进行下一

步添加子设备的操作。

说明:

不要在步骤1中注册的回调函数中进行会阻塞线程操作,如调用IOT_Linkkit_Connect进行子设备

建连,调用IOT_Linkkit_Report进行子设备上下线等。

2. 添加子设备。

添加子设备主要由4个步骤完成。

a) 使用IOTX_LINKKIT_DEV_TYPE_SLAVE参数调用IOT_Linkkit_Open初始化子设备资源。

说明:

如果需要使用动态注册,只需要将设备信息参数的device_secret配置为空字符串即可。启用

动态注册功能需要把子设备的DeviceName事先在物联网控制台预注册。

b) 调用IOT_Linkkit_Connect将子设备连上云端,这个接口为同步接口,会自动完成子设备注册

和拓扑关系的添加。

c) 使用ITM_MSG_LOGIN参数调用IOT_Linkkit_Report完成子设备上线操作。

d) 在ITE_INITIALIZE_COMPLETED事件处理函数中确认对应的子设备连云初始化完成后,便可以

进行子设备与云端的数据交互了。

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");

文档版本:20200417 471

Page 484: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

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;}

注意:

使用相同ProductKey, DeviceName重复调用IOT_Linkkit_Open初始化子设备资源,将返回相

同的devid,SDK不会重复创建子设备资源。因此,在子设备创建成功后,用户可通过重复调用

IOT_Linkkit_Open来查询ProductKey, DeviceName对应的子设备devid。

3. 子设备管理相关操作。

a) 子设备登出。

使用ITM_MSG_LOGOUT选项调用IOT_Linkkit_Report即可完成子设备登出。子设备登出功能

主要用于通知云端控制台设备处于离线状态。

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

472 文档版本:20200417

Page 485: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

b) 获取子设备列表。

网关可以用ITM_MSG_QUERY_TOPOLIST选项来调用IOT_Linkkit_Query以获取与其存在拓扑

关系的所有子设备信息。列表信息将在ITE_TOPOLIST_REPLY事件回调中返回。

c) 删除子设备拓扑关系。

用户可以用ITM_MSG_DELETE_TOPO选项调用IOT_Linkkit_Report以删除参数devid指定的子

设备拓扑关系,执行该命令后云端不会再将该子设备与本网关进行关联。

d) 子设备OTA。

用户使用IOT_Ioctl配置要升级的子设备,再用IOT_Linkkit_Query来触发子设备升级。

• 调用IOT_RegisterCallback注册固件升级所用的回调函数user_fota_event_handler。

IOT_RegisterCallback(ITE_FOTA, user_fota_event_handler);IOT_RegisterCallback(ITE_INITIALIZE_COMPLETED, user_initialized);

• 使用IOTX_LINKKIT_DEV_TYPE_MASTER参数调用IOT_Linkkit_Open初始化主设备资源。

iotx_linkkit_dev_meta_info_t master_meta_info;

memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t));memcpy(master_meta_info.product_key, PRODUCT_KEY, strlen(PRODUCT_KEY));memcpy(master_meta_info.product_secret, PRODUCT_SECRET, strlen(PRODUCT_SECRET));memcpy(master_meta_info.device_name, DEVICE_NAME, strlen(DEVICE_NAME));memcpy(master_meta_info.device_secret, DEVICE_SECRET, strlen(DEVICE_SECRET));

/* Create Master Device Resources */user_example_ctx->master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info); if (user_example_ctx->master_devid < 0) { EXAMPLE_TRACE("IOT_Linkkit_Open Failed\n"); return -1;}

• 调用IOT_Linkkit_Connect与云端建立连接。

/* Start Connect Aliyun Server */res = IOT_Linkkit_Connect(user_example_ctx->master_devid);if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect Failed\n"); return -1;}

• 添加子设备,进行子设备OTA。

/* Add subdev */while (user_example_ctx->subdev_index < EXAMPLE_SUBDEV_ADD_NUM) { if (user_example_ctx->master_initialized && user_example_ctx->subdev_index >= 0 &&

文档版本:20200417 473

Page 486: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

(0 == current_ota_running) && (user_example_ctx->auto_add_subdev == 1 || 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", subdevArr[user_example_ctx->subdev_index].device_name); } else { EXAMPLE_TRACE("subdev %s add failed", subdevArr[user_example_ctx->subdev_index].device_name); } user_example_ctx->subdev_index++; user_example_ctx->permit_join = 0; /* check each sub dev has remote ota message */ do_subdev_ota(user_example_ctx->subdev_index); /* wait remote ota message */ HAL_SleepMs(10000); }}

• do_subdev_ota函数详解。

用户通过IOT_Ioctl这个接口来切换OTA通道为某个子设备(以devid区分_使用。切换

后,只有这个子设备的升级消息能够被接收到。同时通过IOT_Linkkit_Query接口向云端

查询是否有适合当前子设备的固件版本信息,如果有则走入OTA流程(触发用户自定义

的OTA回调函数user_fota_event_handler)。

void do_subdev_ota(int devid){ if (status_list[devid] == SUB_OTA_SUCCESS) { HAL_Printf("current devid is %d, its has checked remote ota message, skip\n", devid); return; }

if (current_ota_running == 1) { return; }

HAL_Printf("current devid running ota is %d\n", devid); int ota_result = 0; ota_result = IOT_Ioctl(IOTX_IOCTL_SET_OTA_DEV_ID, (void *)(&devid)); if (0 != ota_result) { status_list[devid] = SUB_OTA_FAILED_SET_DEV_ID; HAL_Printf("IOTX_IOCTL_SET_OTA_DEV_ID failed, id is %d\n", devid); return; } ota_result = IOT_Linkkit_Query(devid, ITM_MSG_REQUEST_FOTA_IMAGE, (unsigned char *)current_subdev_version, strlen(current_subdev_version)); HAL_Printf("current devid is %d, ITM_MSG_REQUEST_FOTA_IMAGE ret is %d\n", devid, ota_result); if (0 != ota_result) { status_list[devid] = SUB_OTA_FAILED_QUERY; return; } status_list[devid] = SUB_OTA_SUCCESS;}

474 文档版本:20200417

Page 487: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

4. 子设备数据交互。

子设备与云端的数据交互方法与单品产品完全一致,详情可查看物模型编程章节。

• 调用IOT_Linkkit_Report上报属性,上报透传数据,更新设备标签信息,删除设备标签信息。

• 调用IOT_Linkkit_TriggerEvent进行Event的主动上报。

• 在ITE_RAWDATA_ARRIVED事件回调中接收云端下发的透传数据。

• 在ITE_SERVICE_REQUST事件回调中接收服务请求(同步服务和异步服务)。

• 在ITE_PROPERTY_SET事件回调中处理云端下发的属性设置。

• 在ITE_PROPERTY_GET事件回调中处理本地通信下发的属性获取

注意事项

1. 网关设备必须支持多线程,并使用独立线程用于执行IOT_Linkkit_Yield。

void *user_dispatch_yield(void *args) { while (1){ IOT_Linkkit_Yield(USER_EXAMPLE_YIELD_TIMEOUT_MS); }

return NULL; }

res = HAL_ThreadCreate(&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; }

2. 对接智能生活开放平台时,只有在收到云端下发的ITE_PERMIT_JOIN事件后,才可以执行子设备

添加流程。

当用户通过通过App扫码发起子设备添加时,App将会向云端发送PermitJoin命令,之后云端会

将该命令转发给网关。ITE_PERMIT_JOIN事件会下发子设备的的productKey和允许子设备接入的

时间窗口timeoutSec(一般为60秒),厂商可在此窗口时间内去执行子设备的发现和绑定,并

执行添加子设备流程上报云端,上报成功后便可以在App界面查看到添加的子设备。此功能让子

设备的添加被有效的管控起来,只有在窗口时间内才可以添加子设备int user_permit_join_eve

nt_handler(const char product_key, const int time){ user_example_ctx_t user_examp

le_ctx = user_example_get_ctx();。

EXAMPLE_TRACE(“Product Key: %s, Time: %d”, product_key, time);user_example_ctx->permit_join = 1;return 0;}

文档版本:20200417 475

Page 488: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

```

3. 在SDK主目录的make.setting文件中添加FEATURE_DEVICE_MODEL_GATEWAY=y,再运

行make命令即可编译出网关例程。

网关相关API

函数名 说明

IOT_Linkkit_Open 创建本地资源,在进行网络报文交互之前,必须先调用此接口,得到一个会话的句柄。

IOT_Linkkit_Connect 对主设备/网关来说,将会建立设备与云端的通信。对于子设备来说,将向云端注册该子设备(若需要),并添加主子设备拓扑关系。

IOT_Linkkit_Yield 若SDK占有独立线程,该函数内容为空,否则表示将CPU交给SDK让其接收网络报文并将消息分发到用户的回调函数中。

IOT_Linkkit_Close 若入参中的会话句柄为主设备/网关,则关闭网络连接并释放SDK为该会话所占用的所有资源。

IOT_Linkkit_Report 向云端发送没有云端业务数据下发的上行报文,包括属性值/设备标签/二进制透传数据/子设备管理等各种报文。

IOT_Linkkit_Query 向云端发送存在云端业务数据下发的查询报文,包括OTA状态查询/OTA固件下载/子设备拓扑查询/NTP时间查询等各种报文。

IOT_Linkkit_TriggerEvent 向云端发送事件报文、如错误码、异常告警等。

其他通用函数名 说明

IOT_Ioctl 设置SDK运行时的可配置选项

IOT_RegisterCallback 注册事件回调函数

1.2.1.15 WiFi配网

1.2.1.15.1 WiFi配网概述WiFi设备需要连接到WiFi热点(WiFi AP)之后才能与其它设备进行基于IP的通信, 我们将WiFi设备获取

到WiFi热点的SSID/密码的步骤称为WiFi配网

对于手机/电脑/平板而言, 用户可以通过键盘或者触摸屏输入WiFi热点的SSID/密码

但是对于没有键盘, 没有触摸屏的IoT设备而言, 如何获取WiFi热点的SSID/密码是实现设备网络管理的

第一个关键步骤

476 文档版本:20200417

Page 489: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

为了节约WiFi设备厂商开发配网方案的开发成本, 阿里为WiFi类型的IoT设备提供了几种配网方案, 设

备厂商可以根据自己的需要相应集成

注:

• 目前阿里提供的配网方案仅针对WiFi家庭网络(即设备使用SSID/密码连接一个WiFi热点), 暂不支

持对WiFi企业网络场景进行配网(使用SSID/用户名/密码方式连接WiFi热点)

• 如果设备可以通过触摸屏/键盘, 或其它方式获取到AP热点的SSID/密码, 可以不用移植下面的配网

方案, 因为下面的配网方案的移植工作量和难度都并不小

现有方案

现有的C-SDK中已支持如下的几种WiFi配网模式

• 一键配网(smartconfig): 手机app直接给IoT设备配网, 设备需能够工作在嗅探(sniffer)状态

• 手机热点配网(phone-as-ap): 手机app充当临时热点, 直接给IoT设备配网

• 路由器热点配网(router-ap): 输出到路由器厂商/通信运营商

• 零配(zeroconfig): 用已配网的IoT设备给其它的IoT设备配网

• 设备热点配网(dev-ap): IoT设备充当临时热点, 手机app连接设备热点为其配网, 设备需能够工作

在热点(ap)状态

文档版本:20200417 477

Page 490: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

配网通用HAL移植说明

设备端针对不同的配网方式需要实现的HAL函数有一定区别。其中部分HAL是SDK公共的,部分HAL是

配网模块独有但是所有配网方式公共的,本文档列举所有公共部分HAL,即配网能工作必须要实现的

HAL;针对每种不同的配网模式分特有的HAL将在每种配网模式中进行单独列举。

配网依赖的Linkkit SDK公共HAL

序号 函数名 说明

1 HAL_MutexCreate 创建一个互斥量对象, 返回指向所创建互斥量的指针,用于同步访问, 对于仅支持单线程应用, 可实现为空函数

2 HAL_MutexDestroy 销毁一个互斥量对象, 释放资源

3 HAL_MutexLock 锁住一个互斥量

4 HAL_MutexUnlock 解锁一个互斥量

5 HAL_UptimeMs 获取设备从上电到当前时刻所经过的毫秒数

6 HAL_Malloc 申请一块堆内存

7 HAL_Free 释放参数ptr指向的一块堆内存, 当传入的参数为NULL时不执行任何操作

8 HAL_SleepMs 睡眠函数, 使当前执行线程睡眠指定的毫秒数

478 文档版本:20200417

Page 491: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

序号 函数名 说明

9 HAL_GetProductKey 获取设备的ProductKey, 用于标识设备的品类, 四元组之一

10 HAL_GetProductSecret 获取设备的ProductSecret, 用于标识设备的品类, 四元组之一

11 HAL_GetDeviceName 获取设备的DeviceName, 用于标识设备单品的名字,四元组之一

12 HAL_GetDeviceSecret 获取设备的DeviceSecret, 用于标识设备单品的密钥,四元组之一

13 HAL_Kv_Set Flash中写入键值对(Key-Value)

14 HAL_Kv_Get Flash中读取键值对的Value

15 HAL_Aes128_Init 初始化AES加密的结构体

16 HAL_Aes128_Destroy 销毁AES加密的结构体

17 HAL_Aes128_Cbc_Decrypt 以AES-CBC-128方式, 根据HAL_Aes128_Init()时传入的密钥解密指定的密文

18 HAL_Aes128_Cfb_Decrypt 以AES-CFB-128方式, 根据HAL_Aes128_Init()时传入的密钥解密指定的密文

19 HAL_Timer_Create 根据Name、TimerFunc和用户上下文创建Timer

20 HAL_Timer_Start Timer开始计时,Timer超时时调用回调函数TimerFunc

21 HAL_Timer_Stop 停止Timer计时

22 HAL_Timer_Delete 删除Timer,释放资源

• 包括配网模块在内的SDK公用HAL

配网模块公共HAL

序号 函数名 说明

1 HAL_Awss_Get_Timeout_Interval_Ms

获取配网服务(AWSS)的超时时间长度, 单位是毫秒

2 HAL_Sys_Net_Is_Ready 检查Wi-Fi网卡、芯片或模组当前的IP地址是否有效

3 HAL_Wifi_Get_Ap_Info 获取设备所连接的热点(Access Point)的信息

4 HAL_Awss_Close_Monitor 关闭监听(Monitor)模式

5 HAL_Awss_Open_Monitor 设备工作在监听(Monitor)模式, 并在收到802.11帧的时候调用被传入的回调函数(包括管理帧和数据帧)

文档版本:20200417 479

Page 492: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

序号 函数名 说明

6 HAL_Awss_Switch_Channel 设置Wi-Fi设备切换到指定的信道(channel)上

7 HAL_Awss_Get_Channelscan_Interval_Ms

获取在每个信道(channel)上扫描的时间长度, 单位是毫秒

8 HAL_Wifi_Get_Mac 获取设备的MAC地址, 格式应当是”XX:XX:XX:XX:XX:XX”

9 HAL_Awss_Get_Conn_Encrypt_Type

获取基于连接的配网服务(热点配网/路由器配网/零配)的安全等级

10 HAL_Awss_Connect_Ap 要求Wi-Fi网卡连接指定热点(Access Point)的函数,bssid指定特定AP,另外bssid也可能为空或无效值(全0或全0xff)

注:

• 配网通用HAL,仅配网模块调用

1.2.1.15.2 一键配网一键配网方案中, 手机将WiFi热点的SSID/密码通过特殊编码方法在WiFi的数据或管理帧上进行广播发

设备可监听WiFi数据帧或管理帧来将SSID/密码进行解码, 然后用获取到的SSID/密码去连接WiFi热点

工作原理如下所示

说明

• 手机连接到WiFi热点上, 然后在固定的信道上广播发送SSID/密码的编码字节

• 设备轮询所有的WiFi信道去检测是否有配网通告, 如果检测到则从配网通告中解码出WiFi热点的

SSID/密码

注: IoT设备大多数只支持2.4GHz频段, 所以目前的一键配网方案设备端实现只是在2.4GHz的1~13信

道上进行配网帧检测

480 文档版本:20200417

Page 493: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如何配置使用这种配网模式

通过menuconfig选择配网模块并选定一键配网:

make distclean

make menuconfig

使能配网:

选择一键配网:

文档版本:20200417 481

Page 494: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API使用范例

下面是设备上电后的配网代码示例:

uint8_t bssid[ETH_ALEN] = {0};char ssid[HAL_MAX_SSID_LEN] = {0};char passwd[HAL_MAX_PASSWORD_LEN] = {0};// Users need to get the stord ssid/passwd, to decide whether to start wifi provisioning serviceif (INVALID_SSID(ssid) || INVALID_BSSID(bssid) ) { awss_start();} else { HAL_Awss_Connect_Ap(TIMEOUT_MS, ssid, passwd, 0, 0, bssid, 0);}// Note:// 1. Device wouldn't parse awss packet until application calls awss_config_press// 2. Application can detect butturn press or the others method of user touch// to call the operation of calling awss_config_press.

上面代码演示了上电后根据设备内是否存储了ssid/password来判断是否需要启动配网. 启动配网后

出于安全考虑并不会直接解awss包进行配网, 当真正需要配网时, 需要调用awss_config_press接口

使能配网:

extern int awss_config_press(); awss_config_press();

配网过程状态监控 如果应用程序需要感知配网过程中的状态变化, 可以注册事件回调函数, 当相关事

件发生时, 配网模块会调用回调函数告知具体的事件, 设备商可以在相关事件中操作LED指示灯的亮或

灭, 或者通过快闪/慢闪来告知用户状态的变化, 也可以播放声音来告知用户状态

参考示例如下:

// 注册事件回调函数, 注册配网事件回调一定要需在awss_start之前调用iotx_event_regist_cb(linkkit_event_monitor);// linkkit_event_monitor是事件回调函数参考事件:static void linkkit_event_monitor(int event){ switch (event) { case IOTX_AWSS_START: // AWSS start without enbale, just supports device discover // operate led to indicate user LOG("IOTX_AWSS_START"); break; case IOTX_AWSS_ENABLE: // AWSS enable, AWSS doesn't parse awss packet until AWSS is enabled. LOG("IOTX_AWSS_ENABLE"); // operate led to indicate user break; case IOTX_AWSS_LOCK_CHAN: // AWSS lock channel(Got AWSS sync packet) LOG("IOTX_AWSS_LOCK_CHAN"); // operate led to indicate user break; case IOTX_AWSS_PASSWD_ERR: // AWSS decrypt passwd error LOG("IOTX_AWSS_PASSWD_ERR"); // operate led to indicate user

482 文档版本:20200417

Page 495: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

break; case IOTX_AWSS_GOT_SSID_PASSWD: LOG("IOTX_AWSS_GOT_SSID_PASSWD"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA: // AWSS try to connnect adha (device // discover, router solution) LOG("IOTX_AWSS_CONNECT_ADHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA_FAIL: // AWSS fails to connect adha LOG("IOTX_AWSS_CONNECT_ADHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA: // AWSS try to connect aha (AP solution) LOG("IOTX_AWSS_CONNECT_AHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA_FAIL: // AWSS fails to connect aha LOG("IOTX_AWSS_CONNECT_AHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_SETUP_NOTIFY: // AWSS sends out device setup information // (AP and router solution) LOG("IOTX_AWSS_SETUP_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER: // AWSS try to connect destination router LOG("IOTX_AWSS_CONNECT_ROUTER"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER_FAIL: // AWSS fails to connect destination // router. LOG("IOTX_AWSS_CONNECT_ROUTER_FAIL"); // operate led to indicate user break; case IOTX_AWSS_GOT_IP: // AWSS connects destination successfully and got // ip address LOG("IOTX_AWSS_GOT_IP"); // operate led to indicate user break; case IOTX_AWSS_SUC_NOTIFY: // AWSS sends out success notify (AWSS // sucess) LOG("IOTX_AWSS_SUC_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_BIND_NOTIFY: // AWSS sends out bind notify information to // support bind between user and device LOG("IOTX_AWSS_BIND_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_ENABLE_TIMEOUT: // AWSS enable timeout // user needs to enable awss again to support get ssid & passwd of router LOG("IOTX_AWSS_ENALBE_TIMEOUT"); // operate led to indicate user break; case IOTX_CONN_CLOUD: // Device try to connect cloud LOG("IOTX_CONN_CLOUD"); // operate led to indicate user break; case IOTX_CONN_CLOUD_FAIL: // Device fails to connect cloud, refer to // net_sockets.h for error code LOG("IOTX_CONN_CLOUD_FAIL");

文档版本:20200417 483

Page 496: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

// operate led to indicate user break; case IOTX_CONN_CLOUD_SUC: // Device connects cloud successfully LOG("IOTX_CONN_CLOUD_SUC"); // operate led to indicate user break; case IOTX_RESET: // Linkkit reset success (just got reset response from // cloud without any other operation) LOG("IOTX_RESET"); // operate led to indicate user break; default: break; }}

API接口说明

序号 函数名 说明

1 awss_start 开启配网服务(设备热点配网除外)

2 awss_config_press

使能配网, 开始解包

3 awss_stop 关闭配网服务(设备热点配网除外)

应用场景

awss_start

调用该API用于启动配网服务. 启动配网服务的场景包括:

设备首次上电, 设备上不存在热点SSID/密码. 用户希望设备重新进行配网 调用该配网服务后, 设备进

入配网发现状态, 用于让网络中的其它设备发现自己的存在. 但是在这个状态中, 设备并不会接受来自

手机或者其它设备推送的SSID/密码

设备上电时若已有SSID/密码, 直接调用HAL_Awss_Connect_Ap()去连接WiFi热点

awss_config_press

为了安全考虑, 设备上通常具备一个配网按键, 当该按键被按下时设备才会接受来自手机或者其它设备

推送的SSID/密码, 设备商需要实现代码来感知配网按键被按下, 并调用本函数让设备接收手机或者其

它设备推送的SSID/密码信息

该函数被调用之后, 只有在HAL_Awss_Get_Timeout_Interval_Ms()指定的时间间隔内会接收手机或

者设备推送的SSID/密码

484 文档版本:20200417

Page 497: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

说明:

• 若设备无法设计一个专门的配网按键, 可以通过长按(比如3秒)设备上的某个按键来表示允许接收

WiFi热点信息.

• 若设备希望设备上电就可以接受手机或者其它设备推送的WiFi热点信息, 那么可以调用awss_start

()之后直接调用awss_config_press()

awss_stop

调用该API用于停止当前配网. 停止服务的场景包括:

• 当前不需要配网, 希望停止配网服务

• 希望通过其他途径配网, 切换配网(如设备热点配网, 第三方配网)

需要对接的HAL接口

除wifi配网概述里面列出的通用HAL API需要对接外, 还需要对接以下HAL:

序号 函数名 说明

1 HAL_Awss_Get_Encrypt_Type

获取smartconfig/设备热点配网服务的安全等级

说明:

配网的安全等级必须小于等于Link kit连云的安全等级, 比如Link kit连云设置为一型一密, 此处设置为

4会出现配网失败的情况.

1.2.1.15.3 手机热点配网手机热点方案中, 手机上启动一个临时的配网热点, 其SSID/密码是固定的。然后WiFi设备通过预置

的SSID/密码连接到手机的临时热点,手机将连接路由器热点的SSID/密码(AES加密)发送给WiFi设备,

然后WiFi设备就使用手机发送过来的SSID/密码(AES解密)连接路由器

工作原理如下所示

说明

• 对于运行iOS的手机、或者高版本安卓的手机,用户需要手动在手机上配置开启临时热点, 并输入

路由器的上网热点信息, 用户操作比较繁琐

文档版本:20200417 485

Page 498: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

如何配置使用这种配网模式

通过menuconfig选择配网模块并选定手机热点配网:

make distclean

make menuconfig

使能配网:

选择手机热点配网:

486 文档版本:20200417

Page 499: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

API使用范例

下面是设备上电后的配网代码示例:

uint8_t bssid[ETH_ALEN] = {0};char ssid[HAL_MAX_SSID_LEN] = {0};char passwd[HAL_MAX_PASSWORD_LEN] = {0};// Users need to get the stord ssid/passwd, to decide whether to start wifi provisioning serviceif (INVALID_SSID(ssid) || INVALID_BSSID(bssid) ) { awss_start();} else { HAL_Awss_Connect_Ap(TIMEOUT_MS, ssid, passwd, 0, 0, bssid, 0);}// Note:// 1. Device wouldn't parse awss packet until application calls awss_config_press// 2. Application can detect butturn press or the others method of user touch// to call the operation of calling awss_config_press.

上面代码演示了上电后根据设备内是否存储了ssid/password来判断是否需要启动配网. 启动配网后

出于安全考虑并不会直接解awss包进行配网, 当真正需要配网时, 需要调用awss_config_press接口

使能配网:

extern int awss_config_press(); awss_config_press();

配网过程状态监控 如果应用程序需要感知配网过程中的状态变化, 可以注册事件回调函数, 当相关事

件发生时, 配网模块会调用回调函数告知具体的事件, 设备商可以在相关事件中操作LED指示灯的亮或

灭, 或者通过快闪/慢闪来告知用户状态的变化, 也可以播放声音来告知用户状态

参考示例如下:

// 注册事件回调函数, 注册配网事件回调一定要需在awss_start之前调用iotx_event_regist_cb(linkkit_event_monitor);// linkkit_event_monitor是事件回调函数参考事件:static void linkkit_event_monitor(int event){ switch (event) { case IOTX_AWSS_START: // AWSS start without enbale, just supports device discover // operate led to indicate user LOG("IOTX_AWSS_START"); break; case IOTX_AWSS_ENABLE: // AWSS enable, AWSS doesn't parse awss packet until AWSS is enabled. LOG("IOTX_AWSS_ENABLE"); // operate led to indicate user break; case IOTX_AWSS_LOCK_CHAN: // AWSS lock channel(Got AWSS sync packet) LOG("IOTX_AWSS_LOCK_CHAN"); // operate led to indicate user break; case IOTX_AWSS_PASSWD_ERR: // AWSS decrypt passwd error LOG("IOTX_AWSS_PASSWD_ERR"); // operate led to indicate user

文档版本:20200417 487

Page 500: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

break; case IOTX_AWSS_GOT_SSID_PASSWD: LOG("IOTX_AWSS_GOT_SSID_PASSWD"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA: // AWSS try to connnect adha (device // discover, router solution) LOG("IOTX_AWSS_CONNECT_ADHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA_FAIL: // AWSS fails to connect adha LOG("IOTX_AWSS_CONNECT_ADHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA: // AWSS try to connect aha (AP solution) LOG("IOTX_AWSS_CONNECT_AHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA_FAIL: // AWSS fails to connect aha LOG("IOTX_AWSS_CONNECT_AHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_SETUP_NOTIFY: // AWSS sends out device setup information // (AP and router solution) LOG("IOTX_AWSS_SETUP_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER: // AWSS try to connect destination router LOG("IOTX_AWSS_CONNECT_ROUTER"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER_FAIL: // AWSS fails to connect destination // router. LOG("IOTX_AWSS_CONNECT_ROUTER_FAIL"); // operate led to indicate user break; case IOTX_AWSS_GOT_IP: // AWSS connects destination successfully and got // ip address LOG("IOTX_AWSS_GOT_IP"); // operate led to indicate user break; case IOTX_AWSS_SUC_NOTIFY: // AWSS sends out success notify (AWSS // sucess) LOG("IOTX_AWSS_SUC_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_BIND_NOTIFY: // AWSS sends out bind notify information to // support bind between user and device LOG("IOTX_AWSS_BIND_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_ENABLE_TIMEOUT: // AWSS enable timeout // user needs to enable awss again to support get ssid & passwd of router LOG("IOTX_AWSS_ENALBE_TIMEOUT"); // operate led to indicate user break; case IOTX_CONN_CLOUD: // Device try to connect cloud LOG("IOTX_CONN_CLOUD"); // operate led to indicate user break; case IOTX_CONN_CLOUD_FAIL: // Device fails to connect cloud, refer to // net_sockets.h for error code LOG("IOTX_CONN_CLOUD_FAIL");

488 文档版本:20200417

Page 501: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

// operate led to indicate user break; case IOTX_CONN_CLOUD_SUC: // Device connects cloud successfully LOG("IOTX_CONN_CLOUD_SUC"); // operate led to indicate user break; case IOTX_RESET: // Linkkit reset success (just got reset response from // cloud without any other operation) LOG("IOTX_RESET"); // operate led to indicate user break; default: break; }}

API接口说明

序号 函数名 说明

1 awss_start 开启配网服务(设备热点配网除外)

2 awss_config_press 使能配网, 开始解包

3 awss_stop 关闭配网服务(设备热点配网除外)

应用场景

awss_start

调用该API用于启动配网服务. 启动配网服务的场景包括:

设备首次上电, 设备上不存在热点SSID/密码. 用户希望设备重新进行配网 调用该配网服务后, 设备进

入配网发现状态, 用于让网络中的其它设备发现自己的存在. 但是在这个状态中, 设备并不会接受来自

手机或者其它设备推送的SSID/密码

设备上电时若已有SSID/密码, 直接调用HAL_Awss_Connect_Ap()去连接WiFi热点

awss_config_press

为了安全考虑, 设备上通常具备一个配网按键, 当该按键被按下时设备才会接受来自手机或者其它设备

推送的SSID/密码, 设备商需要实现代码来感知配网按键被按下, 并调用本函数让设备接收手机或者其

它设备推送的SSID/密码信息

该函数被调用之后, 只有在HAL_Awss_Get_Timeout_Interval_Ms()指定的时间间隔内会接收手机或

者设备推送的SSID/密码

说明:

• 若设备无法设计一个专门的配网按键, 可以通过长按(比如3秒)设备上的某个按键来表示允许接收

WiFi热点信息.

文档版本:20200417 489

Page 502: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 若设备希望设备上电就可以接受手机或者其它设备推送的WiFi热点信息, 那么可以调用awss_start

()之后直接调用awss_config_press()

awss_stop

调用该API用于停止当前配网. 停止服务的场景包括:

• 当前不需要配网, 希望停止配网服务

• 希望通过其他途径配网, 切换配网(如设备热点配网, 第三方配网)

需要对接的HAL接口

除wifi配网概述里面列出的通用HAL API需要对接外, 还需要对接以下HAL:

序号 函数名 说明

1 HAL_Wifi_Send_80211_Raw_Frame

在当前信道(channel)上以基本数据速率(1Mbps)发送裸的802.11帧(raw 802.11 frame)

1.2.1.15.4 设备热点配网方案简述: 设备开启默认热点, 手机搜索发现到热点后连接到设备热点, 手机将连接公网的路由器热点

的SSID/密码(AES加密)发送给WiFi设备, 然后WiFi设备就使用手机发送过来的SSID/密码(AES解密)连

接路由器

工作原理如下所示

• 注:由于设备热点配网需要开启热点模式,而设备一般无法同时开启设备热点与混杂

模式,故设备热点配网与其他配网模式不能同时开启u>,为做区分,我们提供了单独

的api(awss_dev_ap_start和awss_dev_ap_stop)用于开启和关闭设备热点配网。

如何配置使用这种配网模式

通过menuconfig选择配网模块并选定手机热点配网:

make distclean

make menuconfig

使能配网:

490 文档版本:20200417

Page 503: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

选择手机热点配网:

API接口说明

序号 函数名 说明

1 awss_dev_ap_start 开启设备热点配网

2 awss_dev_ap_stop 关闭设备热点配网

3 iotx_event_regist_cb 注册linkkit(包括配网)生命周期内相关事件通知

文档版本:20200417 491

Page 504: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

应用场景

int awss_dev_ap_start

调用该API用于启动设备热点配网服务. 启动配网服务的场景包括:

• 设备首次上电, 设备上不存在热点SSID/密码.

• 用户希望设备使用设备热点方式重新进行配网.

调用该配网服务后, 设备进入配网发现状态, 用于让网络中的其它设备发现自己的存在。

此接口无入参,设备热点的ssid与password由SDK生成并调用设备上的相关HAL去启动热点。

int awss_dev_ap_stop

调用该API用于停止当前配网. 停止服务的场景包括:

• 当前不需要配网

• 希望通过其他途径配网

API使用示例

下面是设备上电后的配网代码示例:

uint8_t bssid[ETH_ALEN] = {0};char ssid[HAL_MAX_SSID_LEN] = {0};char passwd[HAL_MAX_PASSWORD_LEN] = {0};// Users need to get the stord ssid/passwd, to decide whether to start wifi provisioning serviceif (INVALID_SSID(ssid) || INVALID_BSSID(bssid) ) { awss_dev_ap_start();} else { HAL_Awss_Connect_Ap(TIMEOUT_MS, ssid, passwd, 0, 0, bssid, 0);}

配网过程状态监控

如果应用程序需要感知配网过程中的状态变化, 可以注册事件回调函数, 当相关事件发生时, 配网模

块会调用回调函数告知具体的事件, 设备商可以在相关事件中操作LED指示灯的亮或灭, 或者通过快

闪/慢闪来告知用户状态的变化, 也可以播放声音来告知用户状态

参考示例如下,开发者需要在具体的事件下嵌入自己产品的处理逻辑:

// 注册事件回调函数, 注册配网事件回调一定要需在awss_start之前调用iotx_event_regist_cb(linkkit_event_monitor);// linkkit_event_monitor是事件回调函数参考事件:static void linkkit_event_monitor(int event){ switch (event) { case IOTX_AWSS_START: // AWSS start without enbale, just supports device discover // operate led to indicate user LOG("IOTX_AWSS_START"); break;

492 文档版本:20200417

Page 505: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

case IOTX_AWSS_ENABLE: // AWSS enable, AWSS doesn't parse awss packet until AWSS is enabled. LOG("IOTX_AWSS_ENABLE"); // operate led to indicate user break; case IOTX_AWSS_LOCK_CHAN: // AWSS lock channel(Got AWSS sync packet) LOG("IOTX_AWSS_LOCK_CHAN"); // operate led to indicate user break; case IOTX_AWSS_PASSWD_ERR: // AWSS decrypt passwd error LOG("IOTX_AWSS_PASSWD_ERR"); // operate led to indicate user break; case IOTX_AWSS_GOT_SSID_PASSWD: LOG("IOTX_AWSS_GOT_SSID_PASSWD"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA: // AWSS try to connnect adha (device // discover, router solution) LOG("IOTX_AWSS_CONNECT_ADHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA_FAIL: // AWSS fails to connect adha LOG("IOTX_AWSS_CONNECT_ADHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA: // AWSS try to connect aha (AP solution) LOG("IOTX_AWSS_CONNECT_AHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA_FAIL: // AWSS fails to connect aha LOG("IOTX_AWSS_CONNECT_AHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_SETUP_NOTIFY: // AWSS sends out device setup information // (AP and router solution) LOG("IOTX_AWSS_SETUP_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER: // AWSS try to connect destination router LOG("IOTX_AWSS_CONNECT_ROUTER"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER_FAIL: // AWSS fails to connect destination // router. LOG("IOTX_AWSS_CONNECT_ROUTER_FAIL"); // operate led to indicate user break; case IOTX_AWSS_GOT_IP: // AWSS connects destination successfully and got // ip address LOG("IOTX_AWSS_GOT_IP"); // operate led to indicate user break; case IOTX_AWSS_SUC_NOTIFY: // AWSS sends out success notify (AWSS // sucess) LOG("IOTX_AWSS_SUC_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_BIND_NOTIFY: // AWSS sends out bind notify information to // support bind between user and device LOG("IOTX_AWSS_BIND_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_ENABLE_TIMEOUT: // AWSS enable timeout

文档版本:20200417 493

Page 506: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

// user needs to enable awss again to support get ssid & passwd of router LOG("IOTX_AWSS_ENALBE_TIMEOUT"); // operate led to indicate user break; case IOTX_CONN_CLOUD: // Device try to connect cloud LOG("IOTX_CONN_CLOUD"); // operate led to indicate user break; case IOTX_CONN_CLOUD_FAIL: // Device fails to connect cloud, refer to // net_sockets.h for error code LOG("IOTX_CONN_CLOUD_FAIL"); // operate led to indicate user break; case IOTX_CONN_CLOUD_SUC: // Device connects cloud successfully LOG("IOTX_CONN_CLOUD_SUC"); // operate led to indicate user break; case IOTX_RESET: // Linkkit reset success (just got reset response from // cloud without any other operation) LOG("IOTX_RESET"); // operate led to indicate user break; default: break; }}

需要对接的HAL接口

• 实现SDK的公共HAL

• 实现配网公共HAL中必须的API

序号 函数名 说明

1 HAL_Sys_Net_Is_Ready 检查Wi-Fi网卡/芯片或模组当前的IP地址是否有效

2 HAL_Wifi_Get_Ap_Info 获取设备所连接的热点(Access Point)的信息

3 HAL_Wifi_Get_Mac 获取设备的MAC地址, 格式应当是"XX:XX:XX:XX:XX:XX"

4 HAL_Awss_Connect_Ap 要求Wi-Fi网卡连接指定热点(Access Point)的函数, bssid指定特定AP, 另外bssid也可能为空或无效值(全0或全0xff)

• 除公共部分HAL API外,用户还必须实现以下特有HAL,否则设备热点配网无法正常工作。

序号 函数名 说明

1 HAL_Awss_Close_Ap 关闭设备热点

2 HAL_Awss_Open_Ap 打开设备热点配网

494 文档版本:20200417

Page 507: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.15.5 零配一键配网、手机热点配网、设备热点配网都需要用户输入热点的SSID/密码, 输入时容易出错并且操作

麻烦,零配是一个不需要用户输入热点信息的配网方案, 它是让一个已连接到上网热点的设备将热点

的SSID/密码发送给待配网的设备

工作原理如下所示

从上面的步骤可以看出, 用户不需要输入上网热点的SSID/密码, 只是选择需要配网的设备并确定即可,

因此用户体验会比较好, 但需要网络中存在一个支持零配的已配网的联网设备

注: 天猫精灵音箱支持通过零配对WiFi设备进行配网, 因此如果希望设备可以被天猫精灵配网, 设备上

需要集成零配方案

如何配置使用这种配网模式

通过menuconfig选择配网模块并选则零配:

make distclean

make menuconfig

使能配网:

文档版本:20200417 495

Page 508: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

选择零配:

注:

• 零配一般作为辅助配网, 即同时还需要选择一种其他配网方式如一键配

API使用范例

下面是设备上电后的配网代码示例:

uint8_t bssid[ETH_ALEN] = {0};char ssid[HAL_MAX_SSID_LEN] = {0};char passwd[HAL_MAX_PASSWORD_LEN] = {0};// Users need to get the stord ssid/passwd, to decide whether to start wifi provisioning serviceif (INVALID_SSID(ssid) || INVALID_BSSID(bssid) ) {

496 文档版本:20200417

Page 509: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

awss_start();} else { HAL_Awss_Connect_Ap(TIMEOUT_MS, ssid, passwd, 0, 0, bssid, 0);}// Note:// 1. Device wouldn't parse awss packet until application calls awss_config_press// 2. Application can detect butturn press or the others method of user touch// to call the operation of calling awss_config_press.

上面代码演示了上电后根据设备内是否存储了ssid/password来判断是否需要启动配网. 启动配网后

出于安全考虑并不会直接解awss包进行配网, 当真正需要配网时, 需要调用awss_config_press接口

使能配网:

extern int awss_config_press(); awss_config_press();

配网过程状态监控 如果应用程序需要感知配网过程中的状态变化, 可以注册事件回调函数, 当相关事

件发生时, 配网模块会调用回调函数告知具体的事件, 设备商可以在相关事件中操作LED指示灯的亮或

灭, 或者通过快闪/慢闪来告知用户状态的变化, 也可以播放声音来告知用户状态

参考示例如下:

// 注册事件回调函数, 注册配网事件回调一定要需在awss_start之前调用iotx_event_regist_cb(linkkit_event_monitor);// linkkit_event_monitor是事件回调函数参考事件:static void linkkit_event_monitor(int event){ switch (event) { case IOTX_AWSS_START: // AWSS start without enbale, just supports device discover // operate led to indicate user LOG("IOTX_AWSS_START"); break; case IOTX_AWSS_ENABLE: // AWSS enable, AWSS doesn't parse awss packet until AWSS is enabled. LOG("IOTX_AWSS_ENABLE"); // operate led to indicate user break; case IOTX_AWSS_LOCK_CHAN: // AWSS lock channel(Got AWSS sync packet) LOG("IOTX_AWSS_LOCK_CHAN"); // operate led to indicate user break; case IOTX_AWSS_PASSWD_ERR: // AWSS decrypt passwd error LOG("IOTX_AWSS_PASSWD_ERR"); // operate led to indicate user break; case IOTX_AWSS_GOT_SSID_PASSWD: LOG("IOTX_AWSS_GOT_SSID_PASSWD"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA: // AWSS try to connnect adha (device // discover, router solution) LOG("IOTX_AWSS_CONNECT_ADHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ADHA_FAIL: // AWSS fails to connect adha

文档版本:20200417 497

Page 510: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

LOG("IOTX_AWSS_CONNECT_ADHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA: // AWSS try to connect aha (AP solution) LOG("IOTX_AWSS_CONNECT_AHA"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_AHA_FAIL: // AWSS fails to connect aha LOG("IOTX_AWSS_CONNECT_AHA_FAIL"); // operate led to indicate user break; case IOTX_AWSS_SETUP_NOTIFY: // AWSS sends out device setup information // (AP and router solution) LOG("IOTX_AWSS_SETUP_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER: // AWSS try to connect destination router LOG("IOTX_AWSS_CONNECT_ROUTER"); // operate led to indicate user break; case IOTX_AWSS_CONNECT_ROUTER_FAIL: // AWSS fails to connect destination // router. LOG("IOTX_AWSS_CONNECT_ROUTER_FAIL"); // operate led to indicate user break; case IOTX_AWSS_GOT_IP: // AWSS connects destination successfully and got // ip address LOG("IOTX_AWSS_GOT_IP"); // operate led to indicate user break; case IOTX_AWSS_SUC_NOTIFY: // AWSS sends out success notify (AWSS // sucess) LOG("IOTX_AWSS_SUC_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_BIND_NOTIFY: // AWSS sends out bind notify information to // support bind between user and device LOG("IOTX_AWSS_BIND_NOTIFY"); // operate led to indicate user break; case IOTX_AWSS_ENABLE_TIMEOUT: // AWSS enable timeout // user needs to enable awss again to support get ssid & passwd of router LOG("IOTX_AWSS_ENALBE_TIMEOUT"); // operate led to indicate user break; case IOTX_CONN_CLOUD: // Device try to connect cloud LOG("IOTX_CONN_CLOUD"); // operate led to indicate user break; case IOTX_CONN_CLOUD_FAIL: // Device fails to connect cloud, refer to // net_sockets.h for error code LOG("IOTX_CONN_CLOUD_FAIL"); // operate led to indicate user break; case IOTX_CONN_CLOUD_SUC: // Device connects cloud successfully LOG("IOTX_CONN_CLOUD_SUC"); // operate led to indicate user break; case IOTX_RESET: // Linkkit reset success (just got reset response from // cloud without any other operation) LOG("IOTX_RESET"); // operate led to indicate user break;

498 文档版本:20200417

Page 511: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

default: break; }}

API接口说明

序号 函数名 说明

1 awss_start 开启配网服务(设备热点配网除外)

2 awss_config_press 使能配网, 开始解包

3 awss_stop 关闭配网服务(设备热点配网除外)

应用场景

int awss_start()

调用该API用于启动配网服务. 启动配网服务的场景包括:

设备首次上电, 设备上不存在热点SSID/密码. 用户希望设备重新进行配网 调用该配网服务后, 设备进

入配网发现状态, 用于让网络中的其它设备发现自己的存在. 但是在这个状态中, 设备并不会接受来自

手机或者其它设备推送的SSID/密码

设备上电时若已有SSID/密码, 直接调用HAL_Awss_Connect_Ap()去连接WiFi热点

int awss_config_press()

为了安全考虑, 设备上通常具备一个配网按键, 当该按键被按下时设备才会接受来自手机或者其它设备

推送的SSID/密码, 设备商需要实现代码来感知配网按键被按下, 并调用本函数让设备接收手机或者其

它设备推送的SSID/密码信息

该函数被调用之后, 只有在HAL_Awss_Get_Timeout_Interval_Ms()指定的时间间隔内会接收手机或

者设备推送的SSID/密码

说明:

• 若设备无法设计一个专门的配网按键, 可以通过长按(比如3秒)设备上的某个按键来表示允许接收

WiFi热点信息.

• 若设备希望设备上电就可以接受手机或者其它设备推送的WiFi热点信息, 那么可以调用awss_start

()之后直接调用awss_config_press()

int awss_stop()

调用该API用于停止当前配网. 停止服务的场景包括:

• 当前不需要配网, 希望停止配网服务

文档版本:20200417 499

Page 512: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 希望通过其他途径配网, 切换配网(如设备热点配网, 第三方配网)

需要对接的HAL接口

除wifi配网概述里面列出的通用HAL API需要对接外, 还需要对接以下HAL:

序号 函数名 说明

1 HAL_Wifi_Enable_Mgmt_Frame_Filter

在站点(Station)模式下使能或禁用对特定管理帧的过滤(只接受包含特定OUI的管理帧)

1.2.1.16 设备reset当设备希望恢复出厂设置时,除了删除设备上本地的配置信息,如果也希望云平台清除一些配置,可

以发送reset消息重置云端状态, 目前包括清除topo关系(如果是子设备会踢出下线), 解除用户和设备

绑定关系、清除该设备的设备快照(针对飞燕平台)。

功能讲解

下面的例子中使用了示例代码 src/dev_reset/examples/dev_reset_example.c

用户通过 IOT_MQTT_Construct 连接云端成功之后, 可使用 IOT_DevReset_Report 接口发送消息到

云端, 对设备进行重置操作

int main(int argc, char *argv[]){ ... ... pclient = IOT_MQTT_Construct(&mqtt_params); if (NULL == pclient) { EXAMPLE_TRACE("MQTT construct failed"); return -1; }

res = IOT_DevReset_Report(&meta_info, example_devrst_evt_handle, NULL); if (res < 0) { return -1; } ... ...}

用户可填写 IOT_DevReset_Report 接口的第二个参数进行回调函数的注册, 当重置消息发送成功时,

会从该回调函数得到云端的应答消息

void example_devrst_evt_handle(iotx_devrst_evt_type_t evt, void *msg){ switch (evt) { case IOTX_DEVRST_EVT_RECEIVED: { iotx_devrst_evt_recv_msg_t *recv_msg = (iotx_devrst_evt_recv_msg_t *)msg; if (recv_msg->msgid != reset_mqtt_packet_id) { return; }

500 文档版本:20200417

Page 513: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

EXAMPLE_TRACE("Receive Reset Responst"); EXAMPLE_TRACE("Msg ID: %d", recv_msg->msgid); EXAMPLE_TRACE("Payload: %.*s", recv_msg->payload_len, recv_msg->payload); reset_reply_received = 1; } break;

default: break; }}

功能API接口

原型

int IOT_DevReset_Report(iotx_dev_meta_info_t *meta_info, iotx_devrst_evt_handle_t handle, void *extended);

接口说明

用于向云端上报设备重置消息, 执行结果通过用户注册的回调函数参数 handle 告知用户

参数说明

参数 数据类型 方向 说明

meta_info iotx_linkkit_dev_meta_info_t

输入 设备的四元组信息

handle iotx_devrst_evt_handle_t

输入 设备重置消息的回调函数

extended void * 输入 扩展参数, 保留

返回值说明

值 说明

>= 0 消息发送成功

< 0 失败

需要对接的HAL接口

函数名 说明

HAL_Snprintf 标准库函数snprintf的HAL实现

文档版本:20200417 501

Page 514: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.17 文件上传SDK的文件上传功能使用HTTP2流式传输协议, 将文件上传至阿里云物联网平台服务器.

• 支持多种上传模式, 如以创建文件的方式上传, 或以覆盖文件的方式上传

• 支持指定上传长度, 并在下次上传时续传, 用户可在上传时根据网络带宽配置上传分配大小(

part_len), 以提高带宽利用效率

本节以 src/http2/http2_example_uploadfile.c 为例讲解如何使用文件上传功能

1. 与云端建立连接

调用IOT_HTTP2_UploadFile_Connect建立HTTP2连接,用户指定设备的三元组信息和服务器地

址/端口号。

http2_upload_conn_info_t conn_info; void *handle;

memset(&conn_info, 0, sizeof(http2_upload_conn_info_t)); conn_info.product_key = HTTP2_PRODUCT_KEY; conn_info.device_name = HTTP2_DEVICE_NAME; conn_info.device_secret = HTTP2_DEVICE_SECRET; conn_info.url = HTTP2_ONLINE_SERVER_URL; conn_info.port = HTTP2_ONLINE_SERVER_PORT;

handle = IOT_HTTP2_UploadFile_Connect(&conn_info, NULL);

if(handle == NULL) { return -1; }

目前各个区域对应的域名和端口如下,其中*符号应使用设备的ProductKey替换,如ProductKey为

a1IgnOND7vI时对应的URL、PORT如下:

#define HTTP2_ONLINE_SERVER_URL "a1IgnOND7vI.iot-as-http2.cn-shanghai.aliyuncs.com"#define HTTP2_ONLINE_SERVER_PORT 443

*.iot-as-http2.cn-shanghai.aliyuncs.com:443 // 上海正式*.iot-as-http2.us-west-1.aliyuncs.com:443 // 美西正式*.iot-as-http2.us-east-1.aliyuncs.com:443 // 美东正式*.iot-as-http2.eu-central-1.aliyuncs.com:443 // 德国正式*.iot-as-http2.ap-southeast-1.aliyuncs.com:443 // 新加坡正式*.iot-as-http2.ap-northeast-1.aliyuncs.com:443 // 日本正式

如果用户关心网络状态,可以注册相应的回调函数,目前支持网络断开连接,和网络重连成功两个回

调函数。

502 文档版本:20200417

Page 515: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

2. 文件上传

使用IOT_HTTP2_UploadFile_Request请求文件上传,例程以UPLOAD_FILE_OPT_BIT_OVERWRITE

的方式上传,每次上传都会覆盖云端的文件。此接口为异步接口,用户可以插入多个上传请求到内部

队列中。

http2_upload_params_t fs_params; http2_upload_result_cb_t result_cb;

memset(&result_cb, 0, sizeof(http2_upload_result_cb_t)); result_cb.upload_completed_cb = upload_file_result; result_cb.upload_id_received_cb = upload_id_received_handle;

memset(&fs_params, 0, sizeof(fs_params)); fs_params.file_path = argv[1]; /* 文件名称以命令行参数传入 */ fs_params.opt_bit_map = UPLOAD_FILE_OPT_BIT_OVERWRITE;

ret = IOT_HTTP2_UploadFile_Request(handle, &fs_params, &result_cb, NULL); if(ret < 0) { return -1; }

例程中注册了2个回调函数, 分别用于接收上传的结果, 和接收云端返回的上传标示符(upload_id).

在SDK调用了upload_file_result后, 文件上传操作便结束了, 用户可进行下一步操作

void upload_file_result(const char *file_path, int result, void *user_data) { upload_end++; EXAMPLE_TRACE("=========== file_path = %s, result = %d, finish num = %d ===========", file_path, result, upload_end); }

void upload_id_received_handle(const char *file_path, const char *upload_id, void *user_data) { EXAMPLE_TRACE("=========== file_path = %s, upload_id = %s ===========", file_path, upload_id);

if (upload_id != NULL) { memcpy(g_upload_id, upload_id, strlen(upload_id)); } }

在上传过程中我们可以在log中看到HTTP2的报文交互:

1. 设备端请求云端打开文件上传的通道:

[inf] on_frame_send_callback(143): [INFO] C ---------> S (HEADERS) stream_id [1][inf] on_frame_send_callback(145): > :method: POST[inf] on_frame_send_callback(145): > :path: /stream/open/c/iot/sys/thing/file/upload[inf] on_frame_send_callback(145): > :scheme: https[inf] on_frame_send_callback(145): > x-auth-name: devicename[inf] on_frame_send_callback(145): > x-auth-param-client-id: a1IgnOND7vI.H2_FS01[inf] on_frame_send_callback(145): > x-auth-param-signmethod: hmacsha1[inf] on_frame_send_callback(145): > x-auth-param-product-key: a1IgnOND7vI[inf] on_frame_send_callback(145): > x-auth-param-device-name: H2_FS01

文档版本:20200417 503

Page 516: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

[inf] on_frame_send_callback(145): > x-auth-param-sign: 8d6b80749ed63823dc16b2c1e7f049bbdd00bf2b[inf] on_frame_send_callback(145): > x-sdk-version: 301[inf] on_frame_send_callback(145): > x-sdk-version-name: 3.0.1[inf] on_frame_send_callback(145): > x-sdk-platform: c[inf] on_frame_send_callback(145): > content-length: 0[inf] on_frame_send_callback(145): > x-file-name: upload1M[inf] on_frame_send_callback(145): > x-file-overwrite: 1[inf] on_begin_headers_callback(393): [INFO] C <--------- S (HEADERS) stream_id [1][inf] on_header_callback(363): < :status: 200[inf] on_header_callback(363): < x-request-id: 1103919500797702144[inf] on_header_callback(363): < x-next-append-position: 0[inf] on_header_callback(363): < x-data-stream-id: DS1103919500889976832[inf] on_header_callback(363): < x-file-upload-id: ULDS1103919500889976832[inf] on_header_callback(363): < x-response-status: 200

1. 通道打开成功,接收到云端返回的文件上传标示符并调用用户回调函数:

upload_id_received_handle|037 :: =========== file_path = upload1M, upload_id = ULDS1103919500889976832 ===========

1. 通道打开成功后,设备端通过HTTP2请求上传文件:

[inf] on_frame_send_callback(143): [INFO] C ---------> S (HEADERS) stream_id [3][inf] on_frame_send_callback(145): > :method: POST[inf] on_frame_send_callback(145): > :path: /stream/send/c/iot/sys/thing/file/upload[inf] on_frame_send_callback(145): > :scheme: https[inf] on_frame_send_callback(145): > content-length: 1048576[inf] on_frame_send_callback(145): > x-data-stream-id: DS1103919500889976832[inf] on_frame_send_callback(145): > x-sdk-version: 301[inf] on_frame_send_callback(145): > x-sdk-version-name: 3.0.1[inf] on_frame_send_callback(145): > x-sdk-platform: c[inf] on_frame_send_callback(145): > x-file-upload-id: ULDS1103919500889976832[dbg] http2_stream_node_search(168): stream node not exist, stream_id = 3[inf] send_callback(63): send_callback data len 10249, session->remote_window_size=16777215![inf] send_callback(72): send_callback data ends len = 10249![dbg] http2_stream_node_search(168): stream node not exist, stream_id = 3[inf] iotx_http2_client_send(563): nghttp2_session_send 0[dbg] _http2_fs_part_send_sync(250): send len = 10240[inf] send_callback(63): send_callback data len 10249, session->remote_window_size=16766975![inf] send_callback(72): send_callback data ends len = 10249![inf] iotx_http2_client_send(563): nghttp2_session_send 0[dbg] _http2_fs_part_send_sync(250): send len = 20480[inf] send_callback(63): send_callback data len 10249, session->remote_window_size=16756735![inf] send_callback(72): send_callback data ends len = 10249![inf] iotx_http2_client_send(563): nghttp2_session_send 0[dbg] _http2_fs_part_send_sync(250): send len = 30720[inf] send_callback(63): send_callback data len 10249, session->remote_window_size=16746495![inf] send_callback(72): send_callback data ends len = 10249![inf] iotx_http2_client_send(563): nghttp2_session_send 0[dbg] _http2_fs_part_send_sync(250): send len = 40960

504 文档版本:20200417

Page 517: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1. 文件上传结束,等待云端上传结构应答,应答中的x-next-append-position便是已上传文件的大

[inf] on_frame_recv_callback(196): on_frame_recv_callback, type = 8[inf] on_frame_recv_callback(197): on_frame_recv_callback, stream_id = 3[inf] on_frame_recv_callback(205): stream user data is not exist[inf] on_begin_headers_callback(393): [INFO] C <--------- S (HEADERS) stream_id [3][inf] on_header_callback(363): < :status: 200[inf] on_header_callback(363): < x-request-id: 1103919501166800896[inf] on_header_callback(363): < x-next-append-position: 1048576[inf] on_header_callback(363): < x-data-stream-id: DS1103919500889976832[inf] on_header_callback(363): < x-response-status: 200[inf] on_frame_recv_callback(196): [dbg] _http2_fs_part_send_sync(250): on_frame_recv_callback, type = 1[inf] on_frame_recv_callback(197): on_frame_recv_callback, stream_id = 3[inf] on_frame_recv_callback(205): send len = 1048576[inf] _http2_fs_node_handle(350): file offset = 1048576 now

1. 最后SDK会关闭文件上传通道:

[inf] on_frame_send_callback(143): [INFO] C ---------> S (HEADERS) stream_id [5][inf] on_frame_send_callback(145): > :method: POST[inf] on_frame_send_callback(145): > :path: /stream/close/c/iot/sys/thing/file/upload[inf] on_frame_send_callback(145): > :scheme: https[inf] on_frame_send_callback(145): > x-data-stream-id: DS1103919500889976832[inf] on_frame_send_callback(145): > x-sdk-version: 301[inf] on_frame_send_callback(145): > x-sdk-version-name: 3.0.1[inf] on_frame_send_callback(145): > x-sdk-platform: c[dbg] http2_stream_node_search(168): stream node not exist, stream_id = 5[inf] iotx_http2_client_send(563): nghttp2_session_send 0[inf] on_begin_headers_callback(393): [INFO] C <--------- S (HEADERS) stream_id [5][inf] on_header_callback(363): < :status: 200[inf] on_header_callback(363): < x-request-id: 1103919502177628160[inf] on_header_callback(363): < x-data-stream-id: DS1103919500889976832[inf] on_header_callback(363): < x-file-crc64ecma: 6947770692288575170[inf] on_header_callback(363): < x-response-status: 200[inf] on_header_callback(363): < x-file-store-id: 101184

3. 断开连接

所有文件上传结束后使用IOT_HTTP2_UploadFile_Disconnect断开云端连接。

ret = IOT_HTTP2_UploadFile_Disconnect(handle);

功能API接口

src/http2/http2_upload_api.h列出了HTTP2文件上传的所有API和相关数据类型定义

src/http2/http2_wrapper.h列出了HTTP2所需的底层接口

文档版本:20200417 505

Page 518: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HTTP2建立连接

接口原型

void *IOT_HTTP2_UploadFile_Connect(http2_upload_conn_info_t *conn_info, http2_status_cb_t *cb);

接口说明

创建HTTP2连接, 并注册相关状态回调函数. 此接口为同步接口, 当建连成功后会返回HTTP2连接句柄.

否则返回NULL

参数说明

参数 数据类型 方向 说明

conn_info http2_upload_conn_info_t *

输入 设备连接信息

cb http2_status_cb_t * 输入 设备状态回调函数结构体指针

返回值说明

值 说明

非NULL 建连成功

NULL 建连失败

参数附加说明

typedef struct { char *product_key; char *device_name; char *device_secret; char *url; int port;} http2_upload_conn_info_t;

• product_key: 三元组之一, 产品标示符

• device_name: 三元组之一, 设备名称

• device_secret: 三元组之一, 识别秘钥

• url: 云端服务器地址

• port: 云端服务器端口

typedef struct { http2_disconnect_cb_t on_disconnect_cb; http2_reconnect_cb_t on_reconnect_cb;

506 文档版本:20200417

Page 519: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

} http2_status_cb_t;

• on_disconnect_cb: HTTP2断连回调函数

• on_reconnect_cb: HTTP2重连回调函数

文件上传请求

接口原型

int IOT_HTTP2_UploadFile_Request(void *http2_handle, http2_upload_params_t *params, http2_upload_result_cb_t *cb, void *user_data);

接口说明

按照指定参数配置上传文件, 并注册相关结果回调函数. 此接口为异步接口, 上传结果由回调函数返回

参数说明

参数 数据类型 方向 说明

http2_handle void * 输入 调用IOT_HTTP2_UploadFile_Connect建连成功后返回的句柄

params http2_upload_params_t *

输入 上传参数结构体指针

cb http2_upload_result_cb_t

输入 上传结构回调函数结构体指针

user_data void * 输入 用户数据

返回值说明

值 说明

0 函数调用成功

< 0 函数调用失败

typedef struct { const char *file_path; /* file path, filename must be ASCII string and strlen < 2014 */ uint32_t part_len; /* maximum content len of one http2 request, must be in range of 100KB ~ 100MB */ const char *upload_id; /* a specific id used to indicate one upload session, only required when UPLOAD_FILE_OPT_BIT_RESUME option set */ uint32_t upload_len; /* used to indicate the upload length, only required when UPLOAD_FILE_OPT_BIT_SPECIFIC_LEN option set */ uint32_t opt_bit_map; /* option bit map, support UPLOAD_FILE_OPT_BIT_OVERWRITE, UPLOAD_FILE_OPT_BIT_RESUME and UPLOAD_FILE_OPT_BIT_SPECIFIC_LEN */} http2_upload_params_t;

文档版本:20200417 507

Page 520: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• file_path: 文件路径, 注意文件名必须为ASCII编码, 且不能使用数字开头

• part_len: 文件上传分片大小, 也即HTTP2请求content_len的最大长度, 必须在100KB ~ 100MB范

围内, 否则会使用http2_config.h里的默认长度

• upload_id: 上传标示符, 由首次上传时返回. 在需要使用断点续传方式上传时需添加opt_bit_map

参数UPLOAD_FILE_OPT_BIT_RESUME, 并指定对应上传标示符

• upload_len: 指定本次请求的长度, 仅在opt_bit_map参数中有配置UPLOAD_FILE_OPT_BIT_

SPECIFIC_LEN时才能起作用

• opt_bit_map: 位定义的选项表, 可以使用按位或的方式配置此选项

- 如opt_bit_map = UPLOAD_FILE_OPT_BIT_OVERWRITE | UPLOAD_FILE_OPT_BIT_

SPECIFIC_LEN表示使用覆盖方式上传指定的文件长度

#define UPLOAD_FILE_OPT_BIT_OVERWRITE (0x00000001)#define UPLOAD_FILE_OPT_BIT_RESUME (0x00000002)#define UPLOAD_FILE_OPT_BIT_SPECIFIC_LEN (0x00000004)

• UPLOAD_FILE_OPT_BIT_OVERWRITE: 使用覆盖的方式上传文件. 如果云端文件已存在, 而未使用

覆盖方式, 则文件上传会失败. 未使用此选项, 将使用创建文件的方式上传文件

• UPLOAD_FILE_OPT_BIT_RESUME: 使用断点续传的方式上传文件. 使用此选项需填写上传标示符

参数(upload_id)

• UPLOAD_FILE_OPT_BIT_SPECIFIC_LEN: 使用指定长度的方式上传. 使用此选项需要填写上传长度

参数(upload_len). 否则无需填写upload_len, 将上传整个文件

typedef struct { http2_upload_id_received_cb_t upload_id_received_cb; http2_upload_completed_cb_t upload_completed_cb;} http2_upload_result_cb_t;

• upload_id_received_cb: 接收到云端服务器返回的上传标示符时, 将调用此回调函数

• upload_completed_cb: 文件上传结束时, 将调用此回调函数, result参数指示了上传结果

HTTP2断开连接

接口原型

int IOT_HTTP2_UploadFile_Disconnect(void *handle);

接口说明

断开参数handle指定的HTTP2连接

508 文档版本:20200417

Page 521: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

http2_handle void * 输入 调用IOT_HTTP2_UploadFile_Connect建连成功后返回的句柄

返回值说明

值 说明

0 函数调用成功

< 0 函数调用失败

需要对接的HAL接口

文件src/http2/http2_wrapper.h中包含了用户对接HTTP2文件上传需要适配的部分HAL接口

函数名 说明

HAL_SSL_Destroy 销毁一个TLS连接, 用于MQTT功能, HTTPS功能

HAL_SSL_Establish 建立一个TLS连接, 用于MQTT功能, HTTPS功能

HAL_SSL_Read 从一个TLS连接中读数据, 用于MQTT功能, HTTPS功能

HAL_SSL_Write 向一个TLS连接中写数据, 用于MQTT功能, HTTPS功能

HAL_MutexCreate 创建一个互斥量对象

HAL_MutexDestroy 销毁一个互斥量对象

HAL_MutexLock 锁住一个互斥量

HAL_MutexUnlock 解锁一个互斥量

HAL_SemaphoreCreate 创建信号量

HAL_SemaphoreDestroy 销毁信号量

HAL_SemaphorePost post信号量

HAL_SemaphoreWait 等待信号量

HAL_ThreadCreate 创建线程

HAL_ThreadDelete 销毁线程

HAL_ThreadDetach 分离线程

HAL_Fopen 打开文件

文档版本:20200417 509

Page 522: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

函数名 说明

HAL_Fread 读取文件数据

HAL_Fwrite 向文件写入数据

HAL_Fseek 设置文件指针stream的位置

HAL_Fclose 关闭文件

HAL_Ftell 得到文件位置指针当前位置相对于文件首的偏移字节数

HAL_Printf 打印函数

HAL_SleepMs 睡眠函数

HAL_Malloc 内存分配

HAL_Free 内存释放

1.2.1.18 HAL列表

1.2.1.18.1 基础HAL释放参数ptr指向的一块堆内存, 当传入的参数为NULL时不执行任何操作

原型

void HAL_Free(_IN_ void *ptr);

接口说明

参数说明

参数 数据类型 方向 说明

ptr void * 输入 指向将要释放的堆内存的指针

返回值说明

void

HAL_GetChipID

原型

char *HAL_GetChipID(_OU_ char cid_str[HAL_CID_LEN]);

510 文档版本:20200417

Page 523: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

获取唯一的芯片ID字符串, 字符串长度不能超过HAL_CID_LEN定义的数值。

注:该HAL只需要芯片商进行适配,如果用户不是芯片商,该HAL返回空字符串即可

参数说明

参数 数据类型 方向 说明

cid_str char[] 输出 存放芯片ID的字符串缓冲区

返回值说明

指向字符串缓冲区的指针

HAL_GetDeviceID

(在2.3.1及以后版本中不需要实现)

原型

int HAL_GetDeviceID(_OU_ char device_id[DEVICE_ID_LEN]);

接口说明

获取设备的DeviceID, 用于标识设备单品的ID

参数说明

参数 数据类型 方向 说明

device_id char[] 输出 存放DeviceID的字符串缓冲区

返回值说明

实际获取到的DeviceID字符串长度

HAL_GetDeviceName

原型

int HAL_GetDeviceName(_OU_ char device_name[DEVICE_NAME_LEN]);

文档版本:20200417 511

Page 524: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

获取设备的DeviceName, 用于唯一标识单个设备的名字, 三元组之一, 在云端控制台注册得到并烧写

到设备中

参数说明

参数 数据类型 方向 说明

device_name char[] 输出 存放DeviceName的字符串缓冲区

返回值说明

实际获取到的DeviceName字符串长度

HAL_GetDeviceSecret

原型

int HAL_GetDeviceSecret(_OU_ char device_secret[DEVICE_SECRET_LEN]);

接口说明

获取设备的DeviceSecret, 用于标识单个设备的密钥, 三元组之一, 在云端控制台注册得到并烧写到设

备中

参数说明

参数 数据类型 方向 说明

device_secret char[] 输出 存放DeviceSecret的字符串缓冲区

返回值说明

实际获取到的DeviceSecret字符串长度

HAL_GetFirmwareVersion

原型

int HAL_GetFirmwareVersion(_OU_ char version[FIRMWARE_VERSION_MAXLEN]);

512 文档版本:20200417

Page 525: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

获取设备的固件版本字符串, 此固件版本号将会用于OTA升级的版本上报。如果设备不准备支持OTA

,该函数返回空串即可。

参数说明

参数 数据类型 方向 说明

version char[] 输出 存放FirmwareVesion的字符串缓冲区

返回值说明

实际获取到的FirmwareVesion字符串长度

HAL_GetModuleID

原型

int HAL_GetModuleID(_OU_ char mid_str[MID_STR_MAXLEN]);

接口说明

获取设备的Module ID, 仅用于紧密合作伙伴。该函数用于模组商上报模组型号,其它角色的用户返

回空串即可。

参数说明

参数 数据类型 方向 说明

mid_str char[] 输出 存放Module ID的字符串缓冲区

返回值说明

实际获取到的Module ID字符串长度

HAL_GetPartnerID

原型

int HAL_GetPartnerID(_OU_ char pid_str[PID_STR_MAXLEN]);

接口说明

获取设备的Partner ID, 仅用于紧密合作伙伴。

文档版本:20200417 513

Page 526: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

pid_str char[] 输出 存放Partner ID的字符串缓冲区

返回值说明

实际获取到的Partner ID字符串长度

HAL_GetProductKey

原型

int HAL_GetProductKey(_OU_ char product_key[PRODUCT_KEY_LEN]);

接口说明

获取设备的ProductKey, 用于标识设备的品类, 三元组之一, 在云端控制台注册得到并烧写到设备中

参数说明

参数 数据类型 方向 说明

product_key char[] 输出 存放ProductKey的字符串缓冲区

返回值说明

实际获取到的ProductKey字符串长度

HAL_GetProductSecret

原型

int HAL_GetProductSecret(_OU_ char product_secret[DEVICE_SECRET_LEN]);

接口说明

获取设备的ProductSecret, 用于标识品类的密钥, 在云端控制台注册得到并烧写到设备中, 在一型一

密的场景下将会使用到此字符串

参数说明

参数 数据类型 方向 说明

product_secret char[] 输出 存放ProductSecret的字符串缓冲区

514 文档版本:20200417

Page 527: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

实际获取到的ProductSecret字符串长度

HAL_GetTimeStr

(在2.3.1及以后版本中不需要实现) 原型

char *HAL_GetTimeStr(_OU_ char *buf, _IN_ int len);

接口说明

获取当前时间字符串

参数说明

参数 数据类型 方向 说明

buf char * 输出 指向时间字符串缓冲区的指针

len int 输入 字符串缓冲区的字节长度

返回值说明

指向时间字符串缓冲区的指针

HAL_Kv_Del

原型

int HAL_Kv_Del(const char *key);

接口说明

删除指定KV数据, 删除key对应的KV对数据, 可以通过擦除Flash或修改文件数据的方式实现持久化数

据的删除

参数说明

参数 数据类型 方向 说明

key const char * 输入 指向key字符串的指针

buffer void * 输出 指向存放获取数据的指针

buffer_len int * 输出 指向存放获取

文档版本:20200417 515

Page 528: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

0 删除成功

-1 删除失败

HAL_Kv_Erase_All

原型

int HAL_Kv_Erase_All(void);

接口说明

擦除所有的KV数据, 可以通过擦除Flash或修改文件数据的方式实现持久化数据的删除

参数说明

void

返回值说明

值 说明

0 操作成功

-1 操作失败

HAL_Kv_Get

原型

int HAL_Kv_Get(const char *key, void *buffer, int *buffer_len);

接口说明

获取KV数据, 获取key对应的KV对数据, 可以通过读取Flash或读取文件的方式实现持久化数据的读取

参数说明

参数 数据类型 方向 说明

key const char * 输入 指向key字符串的指针

buffer void * 输出 指向存放获取数据的指针

buffer_len int * 输出 指向存放获取

516 文档版本:20200417

Page 529: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

0 获取成功

-1 获取失败

HAL_Kv_Set

原型

int HAL_Kv_Set(const char *key, const void *val, int len, int sync);

接口说明

设置KV数据接口, 可通过写flash或写文件的方式实现数据持久化

参数说明

参数 数据类型 方向 说明

key const char * 输入 指向key字符串的指针

val const void * 输入 指向待设置数据的指针

len int 输入 待设置数据的字节长度

sync int 输入 0: 异步接口. 1: 同步接口

返回值说明

值 说明

0 设置成功

-1 设置失败

HAL_Malloc

原型

void *HAL_Malloc(_IN_ uint32_t size);

接口说明

申请一块堆内存

文档版本:20200417 517

Page 530: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

size uint32_t 输入 申请的堆内存大小

返回值说明

值 说明

NULL 内存申请失败

!NULL 指向堆内存首地址的指针

HAL_Printf

原型

void HAL_Printf(_IN_ const char *fmt, ...);

接口说明

打印函数, 用于向串口或其它标准输出打印日志或调试信息, 可参考C99的printf()函数实现

参数说明

参数 数据类型 方向 说明

fmt const char * 输入 格式化字符串

... 可变类型 输入 可变参数列表

返回值说明

void

HAL_Random

HAL_Random 原型

uint32_t HAL_Random(_IN_ uint32_t region);

接口说明

随机数函数, 接受一个无符号数作为范围, 返回0到region范围内的一个随机数

518 文档版本:20200417

Page 531: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

region uint32_t 输入 用于指定随机数范围的无符号数

返回值说明

在指定范围的随机数

HAL_Reboot

原型

void HAL_Reboot(void);

接口说明

设备重启, 调用该接口能实现复位功能

参数说明

void

返回值说明

void

HAL_SetDeviceName

原型

int HAL_SetDeviceName(_IN_ char *device_name);

接口说明

设置设备的DeviceName, 用于标识设备单品的名字, 三元组之一

参数说明

参数 数据类型 方向 说明

device_name char * 输出 指向待传入DeviceName字符串的指针

返回值说明

待设置DeviceName字符串的长度

文档版本:20200417 519

Page 532: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HAL_SetDeviceSecret

原型

int HAL_SetDeviceSecret(_IN_ char *device_secret);

接口说明

设置设备的DeviceSecret, 用于标识设备单品的密钥, 三元组之一

参数说明

参数 数据类型 方向 说明

device_secret char * 输出 指向待传入DeviceSecret字符串的指针

返回值说明

待设置DeviceSecret字符串的长度

HAL_SetProductKey

原型

int HAL_SetProductKey(_IN_ char *product_key);

接口说明

设置设备的ProductKey, 用于标识设备的品类, 三元组之一

参数说明

参数 数据类型 方向 说明

product_key char * 输入 指向待设置ProductKey字符串的指针

返回值说明

待设置ProductKey字符串的长度

HAL_SetProductSecret

原型

int HAL_SetProductSecret(_IN_ char *product_secret);

520 文档版本:20200417

Page 533: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

设置设备的ProductSecret, 用于标识品类的密钥, 在一型一密场景中会使用到此字符串

参数说明

参数 数据类型 方向 说明

product_secret char * 输出 指向待传入ProductSecret字符串的指针

返回值说明

待设置ProductSecret字符串的长度

HAL_SleepMs

原型

void HAL_SleepMs(_IN_ uint32_t ms);

接口说明

睡眠函数, 使当前执行线程睡眠指定的毫秒数

参数说明

参数 数据类型 方向 说明

ms uint32_t 输入 线程挂起的时间, 单位ms

返回值说明

void

HAL_Snprintf

原型

int HAL_Snprintf(_OU_ char *str, _IN_ const int len, _IN_ const char *fmt, ...);

接口说明

打印函数, 向内存缓冲区格式化构建一个字符串, 参考C99标准库函数

文档版本:20200417 521

Page 534: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

str char * 输入 指向字符缓冲区的指针

len int 输入 缓冲区的字符长度

fmt const char * 输入 格式化字符串

... 输入 可变参数列表

返回值说明

实际写入缓冲区的字符串长度

HAL_Srandom

原型

void HAL_Srandom(_IN_ uint32_t seed);

接口说明

随机数播种函数, 使 HAL_Random 的返回值每个随机序列各不相同, 类似C标准库中的srand

参数说明

参数 数据类型 方向 说明

seed uint32_t 输入 用于产生新随机序列的种子

返回值说明

void

HAL_Sys_reboot

原型

void HAL_Sys_reboot(void);

接口说明

系统立即重启

参数说明

void

522 文档版本:20200417

Page 535: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

void

HAL_Timer_Create

原型

void *HAL_Timer_Create(const char *name, void (*func)(void *), void *user_data);

接口说明

创建指定名称的定时器, 同时注册用户回调函数和用户数据

参数说明

参数 数据类型 方向 说明

name const char * 输入 定时器名称字符串

func void (*func)(void *) 输入 用户回调函数

user_data void * 输入 指向用户数据的指针

返回值说明

值 说明

NULL 创建失败

!NULL 创建成功, 返回定时器句柄

HAL_Timer_Delete

原型

int HAL_Timer_Delete(void *timer);

接口说明

删除由HAL_Timer_Create()创建的定时器, 释放资源

参数说明

参数 数据类型 方向 说明

timer void * 输入 定时器句柄, 此句柄由调用HAL_Timer_Create()时返回

文档版本:20200417 523

Page 536: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

0 操作成功

-1 操作失败

HAL_Timer_Start

原型

int HAL_Timer_Start(void *t, int ms);

接口说明

启动定时器

参数说明

参数 数据类型 方向 说明

timer void * 输入 定时器句柄, 此句柄由调用HAL_Timer_Create()时返回

ms int 输入 定时器定时时间, 单位ms

返回值说明

值 说明

0 操作成功

-1 操作失败

HAL_Timer_Stop

原型

int HAL_Timer_Stop(void *t);

接口说明

关闭定时器

524 文档版本:20200417

Page 537: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

timer void * 输入 定时器句柄, 此句柄由调用HAL_Timer_Create()时返回

返回值说明

值 说明

0 操作成功

-1 操作失败

HAL_UptimeMs

原型

uint64_t HAL_UptimeMs(void);

接口说明

获取设备从上电到当前时刻所经过的毫秒数

参数说明

void

返回值说明

设备从上电到当前时刻所经过的毫秒数

HAL_UTC_Get

原型

long long HAL_UTC_Get(void);

接口说明

获取UTC时间, 数值为从Epoch(1970年1月1日00:00:00 UTC)开始所经过的秒数单位

参数说明

void

文档版本:20200417 525

Page 538: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

单位为ms的UTC时间

HAL_UTC_Set

原型

void HAL_UTC_Set(long long ms);

接口说明

设置UTC时间, 设置参数为从Epoch(1970年1月1日00:00:00 UTC)开始所经过的秒数单位

参数说明

参数 数据类型 方向 说明

ms long long 输入 单位为ms的UTC时间

返回值说明

void

HAL_Vsnprintf

原型

int HAL_Vsnprintf(_OU_ char *str, _IN_ const int len, _IN_ const char *fmt, _IN_ va_list ap);

接口说明

格式化输出字符串到指定buffer中, 可参考C标准库的vsnprintf()实现

参数说明

参数 数据类型 方向 说明

str char * 输出 用于存放写入字符串的buffer

len const int 输入 允许写入的最大字符串长度

fmt const char 输入 格式化字符串

ap va_list 输入 可变参数列表

返回值说明

成功写入的字符串长

526 文档版本:20200417

Page 539: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.18.2 MQTT连云HAL销毁由参数handle指定的TLS连接

原型

int32_t HAL_SSL_Destroy(_IN_ uintptr_t handle);

接口说明

参数说明

参数 数据类型 方向 说明

handle uintptr_t 输入 TLS连接句柄

返回值说明

值 说明

< 0 操作失败

= 0 操作成功

HAL_SSL_Establish

原型

uintptr_t HAL_SSL_Establish( _IN_ const char *host, _IN_ uint16_t port, _IN_ const char *ca_crt, _IN_ size_t ca_crt_len);

接口说明

根据指定的服务器网络地址, 服务器端口号和证书文件建立TLS连接, 返回对应的连接句柄

参数说明

参数 数据类型 方向 说明

host const char 输入 指定的TLS服务器网络地址

port uint16_t 输入 指定的TLS服务器端口

ca_crt const char 输入 指向PEM编码的X.509证书的指针

ca_crt_len size_t 输入 证书字节长度

文档版本:20200417 527

Page 540: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

NULL 创建失败

!NULL 创建成功, 返回TLS连接句柄

HAL_SSL_Read

原型

int32_t HAL_SSL_Read(_IN_ uintptr_t handle, _OU_ char *buf, _OU_ int len, _IN_ int timeout_ms);

接口说明

从指定的TLS连接中读取数据, 此接口为同步接口, 如果在超时时间内读取到参数len指定长度的数据

则立即返回, 否则在超时时间到时才解除阻塞返回

参数说明

参数 数据类型 方向 说明

handle uintptr_t 输入 TLS连接句柄

buf char * 输出 指向数据接收缓冲区的指针

len int 输入 数据接收缓冲区的字节大小

timeout_ms int 输入 超时时间

返回值说明

值 说明

-2 TLS连接发生错误

-1 TLS连接被远程设备关闭

0 TLS读超时, 且没有接收到任何数据

> 0 TLS读取到的字节数, TLS读取成功

HAL_SSL_Write

原型

int32_t HAL_SSL_Write(_IN_ uintptr_t handle, _IN_ const char *buf, _IN_ int len, _IN_ int timeout_ms);

528 文档版本:20200417

Page 541: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

从指定的TLS连接中写入数据, 此接口为同步接口, 如果在超时时间内写入了参数len指定长度的数据

则立即返回, 否则在超时时间到时才解除阻塞返回

参数说明

参数 数据类型 方向 说明

handle uintptr_t 输入 TLS连接句柄

buf char * 输入 指向数据发送缓冲区的指针

len int 输入 数据发送缓冲区的字节大小

timeout_ms int 输入 超时时间

返回值说明

值 说明

< 0 TLS连接发生错误

0 TLS写超时, 且没有写入任何数据

> 0 TLS写入的字节数, TLS写入成功

HAL_TCP_Destroy

原型

int32_t HAL_TCP_Destroy(_IN_ uintptr_t fd);

接口说明

销毁由参数fd指定的TCP连接, 释放资源

参数说明

参数 数据类型 方向 说明

fd uintptr_t 输入 TCP连接句柄

文档版本:20200417 529

Page 542: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

< 0 操作失败

= 0 操作成功

HAL_TCP_Establish

原型

uintptr_t HAL_TCP_Establish(_IN_ const char *host, _IN_ uint16_t port);

接口说明

根据指定的服务器网络地址和端口号建立TCP连接, 并返回对应连接句柄

参数说明

参数 数据类型 方向 说明

host const char * 输入 指定TCP服务器的网络地址

port uint16_t 输入 指定TCP服务器的端口号

返回值说明

值 说明

NULL TCP连接建立失败

!NULL TCP连接建立成功, 返回对应的连接句柄

HAL_TCP_Read

原型

int32_t HAL_TCP_Read(_IN_ uintptr_t fd, _OU_ char *buf, _IN_ uint32_t len, _IN_ uint32_t timeout_ms);

接口说明

从指定的TCP连接中读取数据, 此接口为同步接口, 如果在超时时间内读取到参数len指定长度的数据

则立即返回, 否则在超时时间到时才解除阻塞返回

530 文档版本:20200417

Page 543: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

fd uintptr_t 输入 TCP连接句柄

buf char * 输出 指向数据接收缓冲区的指针

len int 输入 数据接收缓冲区的字节大小

timeout_ms int 输入 超时时间

返回值说明

值 说明

-2 TCP连接发生错误

-1 TCP连接被远程设备关闭

0 TCP读超时, 且没有接收到任何数据

> 0 TCP读取成功, 返回读取到的字节数

HAL_TCP_Write

原型

int32_t HAL_TCP_Write(_IN_ uintptr_t fd, _IN_ const char *buf, _IN_ uint32_t len, _IN_ uint32_t timeout_ms);

接口说明

从指定的TCP连接中写入数据, 此接口为同步接口, 如果在超时时间内写入了参数len指定长度的数据

则立即返回, 否则在超时时间到时才解除阻塞返回

参数说明

参数 数据类型 方向 说明

fd uintptr_t 输入 TCP连接句柄

buf char * 输入 指向数据发送缓冲区的指针

len int 输入 数据发送缓冲区的字节大小

timeout_ms int 输入 超时时间

文档版本:20200417 531

Page 544: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

< 0 TCP连接发生错误

0 TCP写超时, 且没有写入任何数据

> 0 TCP入成功, 返回TCP写入的字节数

1.2.1.18.3 线程HAL创建一个互斥量对象, 返回指向所创建互斥量的指针, 用于同步访问, 对于仅支持单线程应用, 可实现

为空函数

原型

void *HAL_MutexCreate(void);

接口说明

参数说明

void

返回值说明

void

HAL_MutexDestroy

原型

void HAL_MutexDestroy(_IN_ void *mutex);

接口说明

销毁一个互斥量对象, 释放资源

参数说明

参数 数据类型 方向 说明

mutex void * 输入 互斥量指针

返回值说明

void

532 文档版本:20200417

Page 545: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HAL_MutexLock

原型

void HAL_MutexLock(_IN_ void *mutex);

接口说明

锁住一个互斥量

参数说明

参数 数据类型 方向 说明

mutex void * 输入 互斥量指针

返回值说明

void

HAL_MutexUnlock

原型

void HAL_MutexUnlock(_IN_ void *mutex);

接口说明

解锁一个互斥量

参数说明

参数 数据类型 方向 说明

mutex void * 输入 互斥量指针

返回值说明

void

HAL_SemaphoreCreate

原型

void *HAL_SemaphoreCreate(void);

接口说明

创建一个计数信号量, 此接口实现必须为原子操作, 对于仅支持单线程应用, 可实现为空函数

文档版本:20200417 533

Page 546: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

void

返回值说明

值 说明

NULL 创建失败

!NULL 创建成功, 返回信号量句柄

HAL_SemaphoreDestroy

原型

void HAL_SemaphoreDestroy(_IN_ void *sem);

接口说明

销毁一个由参数sem指定的信号量, 此接口实现必须为原子操作, 此函数无返回值

参数说明

参数 数据类型 方向 说明

sem void * 输入 信号量指针

返回值说明

void

HAL_SemaphorePost

原型

void HAL_SemaphorePost(_IN_ void *sem);

接口说明

在指定的计数信号量上做自增操作, 解除其它线程的等待, 此接口实现必须为原子操作, 对于仅支持单

线程应用, 可实现为空函数

参数说明

参数 数据类型 方向 说明

sem void * 输入 信号量句柄

534 文档版本:20200417

Page 547: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

void

HAL_SemaphoreWait

原型

int HAL_SemaphoreWait(_IN_ void *sem, _IN_ uint32_t timeout_ms);

接口说明

在指定的计数信号量上等待并做自减操作, 对于仅支持单线程应用, 此接口实现必须为原子操作, 可实

现为空函数

参数说明

参数 数据类型 方向 说明

sem void * 输入 信号量句柄

timeout_ms uint32_t 输入 信号量等待超时时间, 单位ms, 如果参数为PLATFORM_WAIT_INFINITE, 则函数返回只能由获取信号量触发

返回值说明

值 说明

0 函数返回是由信号量触发

-1 函数返回是由超时触发

HAL_ThreadCreate

原型

int HAL_ThreadCreate( _OU_ void **thread_handle, _IN_ void *(*work_routine)(void *), _IN_ void *arg, _IN_ hal_os_thread_param_t *hal_os_thread_param, _OU_ int *stack_used);

接口说明

按照指定入参创建一个线程

文档版本:20200417 535

Page 548: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

thread_handle void ** 输出 指向线程句柄变量的指针

work_routine void *(*work_routine)(void *)

输入 指向线程执行函数的函数指针

arg void * 输入 传递给运行程序的单个参数

hal_os_thread_param

hal_os_thread_param_t *

输入 指向线程初始化参数的指针

stack_used int * 输出 指示平台是否使用栈缓冲区, 0: 未使用. 1: 使用

线程初始化参数定义:

typedef struct _hal_os_thread { hal_os_thread_priority_t priority; /* initial thread priority */ void *stack_addr; /* thread stack address malloced by caller, use system stack by . */ size_t stack_size; /* stack size requirements in bytes; 0 is default stack size */ int detach_state; /* 0: not detached state; otherwise: detached state. */ char *name; /* thread name. */} hal_os_thread_param_t;

线程优先级定义:

typedef enum { os_thread_priority_idle = -3, /* priority: idle (lowest) */ os_thread_priority_low = -2, /* priority: low */ os_thread_priority_belowNormal = -1, /* priority: below normal */ os_thread_priority_normal = 0, /* priority: normal (default) */ os_thread_priority_aboveNormal = 1, /* priority: above normal */ os_thread_priority_high = 2, /* priority: high */ os_thread_priority_realtime = 3, /* priority: realtime (highest) */ os_thread_priority_error = 0x84, /* system cannot determine priority or thread has illegal priority */} hal_os_thread_priority_t;

返回值说明

值 说明

-1 创建失败

0 创建成功

536 文档版本:20200417

Page 549: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HAL_ThreadDelete

原型

void HAL_ThreadDelete(_IN_ void *thread_handle);

接口说明

删除指定的线程

参数说明

参数 数据类型 方向 说明

thread_handle void * 输入 线程句柄, NULL表示当前线程

返回值说明

void

HAL_ThreadDetach

原型

void HAL_ThreadDetach(_IN_ void *thread_handle);

接口说明

将指定线程设置为分离状态

参数说明

参数 数据类型 方向 说明

thread_handle void * 输入 线程句柄, NULL表示当前线程

返回值说明

void

文档版本:20200417 537

Page 550: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.1.18.4 OTA HAL固件持久化功能开始

HAL_Firmware_Persistence_Start

原型

void HAL_Firmware_Persistence_Start(void);

接口说明

参数说明

void

返回值说明

void

HAL_Firmware_Persistence_Stop

原型

int HAL_Firmware_Persistence_Stop(void);

接口说明

固件持久化功能结束

参数说明

void

返回值说明

void

HAL_Firmware_Persistence_Write

原型

int HAL_Firmware_Persistence_Write(_IN_ char *buffer, _IN_ uint32_t length);

接口说明

固件持久化写入固件

538 文档版本:20200417

Page 551: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

buffer char * 输入 指向写入缓冲区的指针

length uint32_t 输入 写入的字节长度

返回值说明

实际写入的字节长度

1.2.1.18.5 WiFi配网HAL以AES-CBC-128的加解密模式, 用HAL_Aes128_Init()被调用时传入的密钥, 解密从src位置起长度为

blockNum块数的密文, 并把明文结果存放到dst起始的内存缓冲区中

原型

typedef void *p_HAL_Aes128_t;

int HAL_Aes128_Cbc_Decrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t blockNum, _OU_ void *dst);

接口说明

参数说明

参数 数据类型 方向 说明

aes void * 输入 这是一个句柄, 是用户调用HAL_Aes128_Init()成功时所得到的返回值, 之后需要作为必选的入参传给所有AES加解密相关的HAL接口

src const void * 输入 指定被解密的源数据的缓冲区首地址, 也就是AES密文的起始地址

blockNum size_t 输入 指定被解密的源数据的缓冲区长度, 以16字节为一个Block, 此参数表达密文总长度是多少个Block, 或者说是16字节的多少倍

文档版本:20200417 539

Page 552: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

dst void * 输出 指定被解密的目的数据的缓冲区首地址, 也就是AES解密后, 存放明文的首地址

返回值说明

值 说明

0 解密成功

-1 解密失败

HAL_Aes128_Cbc_Encrypt

原型

int HAL_Aes128_Cbc_Encrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t blockNum, _OU_ void *dst);

接口说明

以AES-CBC-128的加解密模式, 用HAL_Aes128_Init()被调用时传入的密钥, 加密从src位置起长度为

blockNum块数的明文, 并把密文结果存放到dst起始的内存缓冲区中

参数说明

参数 数据类型 方向 说明

aes void * 输入 这是一个句柄, 是用户调用HAL_Aes128_Init()成功时所得到的返回值, 之后需要作为必选的入参传给所有AES加解密相关的HAL接口

src const void * 输入 指定被加密的源数据的缓冲区首地址, 也就是明文的起始地址

540 文档版本:20200417

Page 553: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

blockNum size_t 输入 指定被加密的源数据的缓冲区长度, 以16字节为一个Block, 此参数表达明文总长度是多少个Block, 或者说是16字节的多少倍

dst void * 输出 指定被加密的目的数据的缓冲区首地址, 也就是AES加密后, 存放AES密文的首地址

返回值说明

值 说明

0 加密成功

-1 加密失败

HAL_Aes128_Cfb_Decrypt

原型

int HAL_Aes128_Cfb_Decrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t length, _OU_ void *dst);

接口说明

CFB模式的AES128解密接口函数, 使用此接口前必须先调用HAL_Aes128_Init()建立AES上下文数据

结构体

参数length为分组数量(AES128一个分组的长度为128bits, 也就是16bytes), 而非字节数

用户在实现此函数时无需考虑padding问题, 因为SDK在调用此接口前已完成padding处理

参数说明

参数 数据类型 方向 说明

aes void * 输入 调用HAL_Aes128_Init()时返回的上下文结构体指针

文档版本:20200417 541

Page 554: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

src const void * 输入 指向密文数据缓冲区的指针

blockNum size_t 输入 密文数据的分组数量, AES128一个分组长度为16bytes

dst void * 输出 指向密文数据缓冲区的指针

返回值说明

值 说明

0 解密成功

-1 解密失败

HAL_Aes128_Cfb_Encrypt

原型

int HAL_Aes128_Cfb_Encrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t length, _OU_ void *dst);

接口说明

CFB模式的AES128加密接口函数, 使用此接口前必须先调用HAL_Aes128_Init()建立AES上下文数据

结构体

参数length为分组数量(AES128一个分组的长度为128bits, 也就是16bytes), 而非字节数

用户在实现此函数时无需考虑padding问题, 因为SDK在调用此接口前已完成padding处理

参数说明

参数 数据类型 方向 说明

aes p_HAL_Aes128_t 输入 调用HAL_Aes128_Init()时返回的上下文结构体指针

src const void * 输入 指向明文数据缓冲区的指针

542 文档版本:20200417

Page 555: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

length size_t 输入 明文数据的分组数量, AES128一个分组长度为16bytes

dst void * 输出 指向密文数据缓冲区的指针

返回值说明

值 说明

0 加密成功

-1 加密失败

HAL_Aes128_Destroy

原型

int HAL_Aes128_Destroy(_IN_ p_HAL_Aes128_t aes);

接口说明

销毁AES加解密算法的上下文结构体, 释放内存资源

参数说明

参数 数据类型 方向 说明

aes p_HAL_Aes128_t 输入 此参数应调用HAL_Aes128_Init()时返回的上下文结构体指针

返回值说明

值 说明

0 操作成功

-1 操作失败

HAL_Aes128_Init

原型

p_HAL_Aes128_t HAL_Aes128_Init(

文档版本:20200417 543

Page 556: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

_IN_ const uint8_t *key, _IN_ const uint8_t *iv, _IN_ AES_DIR_t dir);

接口说明

初始化AES加解密算法的上下文结构体, 并根据dir参数完成AES算法的初始化. 用户可自定义结构体类

型, 但结构体中应包含key, iv等上下文数据

参数说明

参数 数据类型 方向 说明

key const uint8_t * 输入 AES秘钥数组首地址,秘钥数组长度必须>=16bytes

iv const uint8_t * 输入 AES初始向量数组首地址, 初始向量数组的长度必须>=16bytes

dir AES_DIR_t 输入 指定AES算法用途HAL_AES_ENCRYPTION: 表示用于加密HAL_AES_DECRYPTION: 表示用于解密

typedef enum { HAL_AES_ENCRYPTION = 0, // 用于加密 HAL_AES_DECRYPTION = 1, // 用于解密} AES_DIR_t;

返回值说明

指向所初始化的AES加解密上下文结构体的指针. p_HAL_Aes128_t的类型定义如下所示:

typedef void *p_HAL_Aes128_t;

HAL_Awss_Close_Monitor

原型

void HAL_Awss_Close_Monitor(void);

接口说明

设置Wi-Fi网卡离开监听(Monitor)模式, 并开始以站点(Station)模式工作,并不再以Sniffer抓包

544 文档版本:20200417

Page 557: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

void

返回值说明

void

HAL_Awss_Connect_Ap

原型

int HAL_Awss_Connect_Ap( _IN_ uint32_t connection_timeout_ms, _IN_ char ssid[HAL_MAX_SSID_LEN], _IN_ char passwd[HAL_MAX_PASSWD_LEN], _IN_OPT_ enum AWSS_AUTH_TYPE auth, _IN_OPT_ enum AWSS_ENC_TYPE encry, _IN_OPT_ uint8_t bssid[ETH_ALEN], _IN_OPT_ uint8_t channel);

接口说明

要求Wi-Fi网卡连接指定热点(Access Point)的函数,bssid指定特定AP,另外bssid也可能为空或无

效值(全0或全0xff)

参数说明

参数 数据类型 方向 说明

connection_timeout_ms

uint32_t 输入 连接AP的超时时间

ssid char 输入 目的AP的SSID

passwd char 输入 目的AP的PASSWORD

auth enum 输入 目的AP的加密方式, HAL可以忽略

encry enum 输入 目的AP的认证方式, HAL可以忽略

bssid uint8_t 输入 目的AP的BSSID, 该字段可能为NULL或设置为全0

channel uint8_t 输入 目的AP的信道, 该字段可以忽略

文档版本:20200417 545

Page 558: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

0 连接AP和DHCP成功

-1 连接AP和DHCP失败

HAL_Awss_Get_Channelscan_Interval_Ms

原型

int HAL_Awss_Get_Channelscan_Interval_Ms(void);

接口说明

获取在每个信道(channel)上扫描的时间长度, 单位是毫秒,建议200ms~400ms,默认250ms

参数说明

void

返回值说明

时间长度, 单位是毫秒

HAL_Awss_Get_Connect_Default_Ssid_Timeout_Interval_Ms

原型

int HAL_Awss_Get_Connect_Default_Ssid_Timeout_Interval_Ms(void);

接口说明

获取配网服务(AWSS)超时时长到达之后, 去连接默认SSID时的超时时长, 单位是毫秒(该接口已经废

弃,不再使用,不用对接)

参数说明

void

返回值说明

时时长, 单位是毫秒

HAL_Awss_Get_Conn_Encrypt_Type

原型

int HAL_Awss_Get_Conn_Encrypt_Type(void);

546 文档版本:20200417

Page 559: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

获取零配, 热点配网和路由器配网的安全等级

参数说明

void

返回值说明

值 说明

3 aes128cfb with aes-key per product and aes-iv = random

4 aes128cfb with aes-key per device and aes-iv = random

5 aes128cfb with aes-key per manufacture and aes-iv = random

others 无效

HAL_Awss_Get_Encrypt_Type

原型

int HAL_Awss_Get_Encrypt_Type(void);

接口说明

获取smartconfig服务的安全等级

参数说明

void

返回值说明

值 说明

0 open (no encrypt)

1 aes256cfb with default aes-key and aes-iv

2 aes128cfb with default aes-key and aes-iv

3 aes128cfb with aes-key per product and aes-iv = 0

文档版本:20200417 547

Page 560: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

值 说明

4 aes128cfb with aes-key per device and aes-iv = 0

5 es128cfb with aes-key per manufacture and aes-iv = 0

others invalid

HAL_Awss_Get_Timeout_Interval_Ms

原型

int HAL_Awss_Get_Timeout_Interval_Ms(void);

接口说明

获取配网服务(AWSS)的超时时间长度, 单位是毫秒,建议60s或60000ms

参数说明

void

返回值说明

超时时长, 单位是毫秒

HAL_Awss_Open_Monitor

原型

void HAL_Awss_Open_Monitor(_IN_ awss_recv_80211_frame_cb_t cb);

接口说明

设置Wi-Fi网卡工作在监听(Monitor)模式, 并在收到802.11帧的时候调用被传入的回调函数

参数说明

参数 数据类型 方向 说明

cb awss_recv_80211_frame_cb_t

输入 回调函数指针, 当WiFi接收到帧时会调用此函数

/** * @brief 802.11帧的处理函数, 可以将802.11 Frame传递给这个函数 * * @param[in] buf @n 80211 frame buffer, or pointer to struct ht40_ctrl

548 文档版本:20200417

Page 561: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

* @param[in] length @n 80211 frame buffer length * @param[in] link_type @n AWSS_LINK_TYPE_NONE for most rtos HAL, * and for linux HAL, do the following step to check * which header type the driver supported. * @param[in] with_fcs @n 80211 frame buffer include fcs(4 byte) or not * @param[in] rssi @n rssi of packet, range of `[-127, -1]` */typedef int (*awss_recv_80211_frame_cb_t)(char *buf, int length, enum AWSS_LINK_TYPE link_type, int with_fcs, signed char rssi);

返回值说明

void

HAL_Awss_Switch_Channel

原型

void HAL_Awss_Switch_Channel( _IN_ char primary_channel, _IN_OPT_ char secondary_channel, _IN_OPT_ uint8_t bssid[ETH_ALEN]);

接口说明

设置Wi-Fi网卡切换到指定的信道(channel)上

参数说明

参数 数据类型 方向 说明

primary_channel char 输入 首选信道

secondary_channel char 输入 辅助信道(信道带宽为40MHz时才会使用, 信道宽度为20MHz是可以忽略该参数)

bssid uint8_t 输入 次参数已废弃, 可以忽略

返回值说明

void

HAL_RF433_Get_Rssi_Dbm

原型

int HAL_RF433_Get_Rssi_Dbm(void);

文档版本:20200417 549

Page 562: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

获取RF433的接收信号强度(RSSI)(该API已经废弃,不再使用,不用对接)

参数说明

void

返回值说明

信号强度数值, 单位是dBm

HAL_Sys_Net_Is_Ready

原型

int HAL_Sys_Net_Is_Ready(void);

接口说明

检查系统网络是否可用(设备是否已经成功获得IP地址并且当前IP地址可用)

参数说明

void

返回值说明

值 说明

0 网络不可用

1 网络可用

HAL_Wifi_Enable_Mgmt_Frame_Filter

原型

int HAL_Wifi_Enable_Mgmt_Frame_Filter( _IN_ uint32_t filter_mask, _IN_OPT_ uint8_t vendor_oui[3], _IN_ awss_wifi_mgmt_frame_cb_t callback);

接口说明

在站点(Station)模式下使能或禁用对特定管理帧的过滤(只接受包含特定OUI的管理帧)

550 文档版本:20200417

Page 563: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

filter_mask uint32_t 输入 帧过滤参数

vendor_oui uint8_t 输入 WiFi联盟分配的厂商OUI, 如果OUI为NULL,表示不对OUI过滤, 反之要根据OUI过滤

callback awss_wifi_mgmt_frame_cb_t

输入 用于接收802.11帧或者信息元素(IE)的回调函数

返回值说明

值 说明

= 0 发送成功

= -1 发送失败

= -2 不支持

HAL_Wifi_Get_Ap_Info

原型

int HAL_Wifi_Get_Ap_Info( _OU_ char ssid[HAL_MAX_SSID_LEN], _OU_ char passwd[HAL_MAX_PASSWD_LEN], _OU_ uint8_t bssid[ETH_ALEN]);

接口说明

获取所连接的热点(Access Point)的信息

参数说明

参数 数据类型 方向 说明

ssid char 输出 AP的SSID, 该参数可能为NULL

passwd char 输出 AP的Password, 该参数为NULL

文档版本:20200417 551

Page 564: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

bssid uint8_t 输出 AP的BSSID, 该参数可能为NULL,如果bssid不对将导致零配设备发现失败

返回值说明

值 说明

= 0 操作成功

= -1 操作失败

HAL_Wifi_Get_IP

原型

uint32_t HAL_Wifi_Get_IP(_OU_ char ip_str[HAL_IP_LEN], _IN_ const char *ifname);

接口说明

获取Wi-Fi网口的IP地址, 点分十进制格式保存在字符串数组出参, 二进制格式则作为返回值, 并以网络

字节序(大端)表达

参数说明

参数 数据类型 方向 说明

ip_str char[] 输出 存放点分十进制格式的IP地址字符串的数组

ifname const char* 输入 指定Wi-Fi网络接口的名字(如果只有一个网口,可以忽略此参数,该参数可能为NULL)

返回值说明

二进制形式的IP地址, 以网络字节序(大端)组织

HAL_Wifi_Get_Mac

原型

char *HAL_Wifi_Get_Mac(_OU_ char mac_str[HAL_MAC_LEN]);

552 文档版本:20200417

Page 565: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

获取Wi-Fi网口的MAC地址, 格式应当是"XX:XX:XX:XX:XX:XX"

参数说明

参数 数据类型 方向 说明

mac_str char 输出 指向缓冲区数组起始位置的字符指针

返回值说明

指向缓冲区数组起始位置的字符指针

HAL_Wifi_Low_Power

原型

int HAL_Wifi_Low_Power(_IN_ int timeout_ms);

接口说明

使WiFi模组进入省电模式, 并持续一段时间(该API未用,可以暂时不用对接)

参数说明

参数 数据类型 方向 说明

timeout_ms int 输入 指定在多长时间内, WiFi模组都处于省电模式, 单位是毫秒

返回值说明

值 说明

0 设置成功

-1 设置失败

HAL_Wifi_Scan

原型

int HAL_Wifi_Scan(awss_wifi_scan_result_cb_t cb);

文档版本:20200417 553

Page 566: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

启动一次WiFi的空中扫描, 该API是一个阻塞操作, 扫描没有完成不能结束. 所有的AP列表收集完成后,

一个一个通过回调函数告知AWSS,最好不要限制AP的数量,否则可能导致中文GBK编码的SSID热点

配网失败

参数说明

参数 数据类型 方向 说明

cb awss_wifi_scan_result_cb_t

输入 扫描通知回调函数

返回值说明

值 说明

0 扫描正常结束

-1 其他情况

HAL_Wifi_Send_80211_Raw_Frame

原型

int HAL_Wifi_Send_80211_Raw_Frame(_IN_ enum HAL_Awss_Frame_Type type, _IN_ uint8_t *buffer, _IN_ int len);

接口说明

在当前信道(channel)上以基本数据速率(1Mbps)发送裸的802.11帧(raw 802.11 frame)

参数说明

参数 数据类型 方向 说明

type enum HAL_Awss_Frame_Type

输入 查看HAL_Awss_Frame_Type_t定义, 目前只支持FRAME_BEACON和FRAME_PROBE_REQ

buffer uint8_t * 输入 80211裸数据帧, 包括完整的MAC头和FCS域

554 文档版本:20200417

Page 567: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

len int 输入 80211裸帧字节长度

/* 80211帧类型定义 */typedef enum HAL_Awss_Frame_Type { FRAME_ACTION, FRAME_BEACON, FRAME_PROBE_REQ, FRAME_PROBE_RESPONSE, FRAME_DATA} HAL_Awss_Frame_Type_t;

返回值说明

值 说明

= 0 发送成功

= -1 发送失败

HAL_Awss_Open_Ap

原型

int HAL_Awss_Open_Ap(const char *ssid, const char *passwd, int beacon_interval, int hide);

接口说明

开启设备热点(SoftAP模式)

参数说明

参数 数据类型 方向 说明

ssid const char * 输入 热点的ssid字符

passwd const char * 输入 热点的passwd字符

beacon_interval int 输入 热点的Beacon广播周期(广播间隔)

hide int 输入 0, 非隐藏, 其它值:隐藏;

返回值说明

值 说明

0 success

文档版本:20200417 555

Page 568: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

值 说明

-1 unsupported

-2 failure with system error

-3 failure with no memory

-4 failure with invalid parameters

HAL_Awss_Close_Ap

原型

int HAL_Awss_Close_Ap(void);

接口说明

关闭设备热点

参数说明

void

返回值说明

值 说明

0 success

-1 unsupported

-2 failure

1.2.1.18.6 本地通信HAL绑定UDP socket到指定接口, 只接收来自该接口的数据包

HAL_UDP_bindtodevice

原型

int HAL_UDP_bindtodevice(_IN_ intptr_t fd, _IN_ const char *ifname);

556 文档版本:20200417

Page 569: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

参数说明

参数 数据类型 方向 说明

fd intptr_t 输入 指定用来绑定的UDP socket

ifname const char * 输入 指定用来绑定socket的网络接口名字

返回值说明

值 说明

< 0 绑定异常或失败

= 0 绑定成功

HAL_UDP_close

原型

void HAL_UDP_close(_IN_ intptr_t p_socket);

接口说明

销毁指定的UDP连接, 释放资源

参数说明

参数 数据类型 方向 说明

p_socket intptr_t 输入 UDP socket句柄

返回值说明

void

HAL_UDP_close_without_connect

原型

int HAL_UDP_close_without_connect(_IN_ intptr_t sockfd);

文档版本:20200417 557

Page 570: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

销毁指定的UDP连接, 释放资源

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 UDP socket句柄

返回值说明

值 说明

< 0 操作失败

= 0 操作成功

HAL_UDP_create_without_connect

原型

intptr_t HAL_UDP_create_without_connect(_IN_ const char *host, _IN_ unsigned short port);

接口说明

创建一个本地的UDP socket, 但并不发起任何网络交互

参数说明

参数 数据类型 方向 说明

host const char * 输入 UDP目的地址

port unsigned short 输入 UDP目的端口

返回值说明

值 说明

< 0 创建失败

>= 0 创建成功, 返回值为UDP socket句柄

558 文档版本:20200417

Page 571: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HAL_UDP_joinmulticast

原型

int HAL_UDP_joinmulticast(_IN_ intptr_t sockfd, _IN_ char *p_group);

接口说明

在指定的UDP socket上发送加入组播组的请求

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 指定用来发送组播请求的UDP socket

p_group char * 输入 指定要加入的组播组名称

返回值说明

值 说明

< 0 发送过程中出现错误或异常

= 0 发送成功

HAL_UDP_recvfrom

原型

int HAL_UDP_recvfrom(_IN_ intptr_t sockfd, _OU_ NetworkAddr *p_remote, _OU_ unsigned char *p_data, _IN_ unsigned int datalen, _IN_ unsigned int timeout_ms);

接口说明

从指定的UDP句柄接收指定长度数据到缓冲区, 阻塞时间不超过指定时长, 且指定长度若接收完需提前

返回, 源地址保存在p_remote参数中

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 UDP socket句柄

文档版本:20200417 559

Page 572: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

p_remote NetworkAddr * 输出 指向存放源网络地址的指针

p_data unsigned char * 输出 指向数据接收缓冲区的指针

datalen unsigned int 输入 接收缓冲区的字节大小

timeout_ms unsigned int 输入 阻塞的超时时间, 单位ms

返回值说明

值 说明

< 0 接收过程中出现错误或异常

= 0 在指定的timeout_ms时间内, 没有接收到任何数据

> 0 在指定的timeout_ms时间内, 实际接收到的数据字节数

HAL_UDP_sendto

原型

int HAL_UDP_sendto(_IN_ intptr_t sockfd, _IN_ const NetworkAddr *p_remote, _IN_ const unsigned char *p_data, _IN_ unsigned int datalen, _IN_ unsigned int timeout_ms);

接口说明

向指定UDP句柄发送指定长度的数据, 阻塞时间不超过指定时长, 且指定长度若发送完需提前返回

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 UDP socket句柄

p_remote const NetworkAddr * 输入 指向目标网络地址的指针

p_data const unsigned char *

输入 指数据发送缓冲区的指针

datalen unsigned int 输入 待发送数据的字节长度

560 文档版本:20200417

Page 573: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数 数据类型 方向 说明

timeout_ms unsigned int 输入 阻塞的超时时间, 单位ms

返回值说明

值 说明

< 0 发送过程中出现错误或异常

= 0 在指定的timeout_ms时间内, 没有任何数据发送成功

> 0 在指定的timeout_ms时间内, 实际发送的数据字节数

1.2.1.18.7 CoAP连云HAL根据参数p_options指定的证书, 服务器地址和端口建立DTLS连接, 并返回DTLS会话句柄

HAL_DTLSSession_create

原型

DTLSContext *HAL_DTLSSession_create(coap_dtls_options_t *p_options);

接口说明

参数说明

参数 数据类型 方向 说明

p_options coap_dtls_options_t * 输入 指向coap_dtls_options_t结构体类型选项数据的指针

typedef struct { unsigned char *p_ca_cert_pem; // 指向PEM编码的X.509证书的指针 char *p_host; // 指向DTLS服务器网络地址的指针 unsigned short port; // DTLS服务器端口} coap_dtls_options_t;

返回值说明

DTLS会话句柄

文档版本:20200417 561

Page 574: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HAL_DTLSSession_free

原型

unsigned int HAL_DTLSSession_free(DTLSContext *context);

接口说明

销毁由参数context指定的DTLS会话, 释放资源

参数说明

参数 数据类型 方向 说明

context DTLSContext * 输入 DTLS会话句柄

返回值说明

值 说明

0 操作成功

> 0 操作错误码

DTLS错误码:

define DTLS_ERROR_BASE (1<<24)define DTLS_INVALID_PARAM (DTLS_ERROR_BASE | 1) // 无效参数define DTLS_INVALID_CA_CERTIFICATE (DTLS_ERROR_BASE | 2) // 无效证书define DTLS_HANDSHAKE_IN_PROGRESS (DTLS_ERROR_BASE | 3) // 正在握手define DTLS_HANDSHAKE_FAILED (DTLS_ERROR_BASE | 4) // 握手失败define DTLS_FATAL_ALERT_MESSAGE (DTLS_ERROR_BASE | 5) // 致命警告消息define DTLS_PEER_CLOSE_NOTIFY (DTLS_ERROR_BASE | 6) // 对方打开连接define DTLS_SESSION_CREATE_FAILED (DTLS_ERROR_BASE | 7) // 会话创建失败define DTLS_READ_DATA_FAILED (DTLS_ERROR_BASE | 8) // 数据读取失败

HAL_DTLSSession_read

原型

unsigned int HAL_DTLSSession_read(DTLSContext *context, unsigned char *p_data, unsigned int *p_datalen, unsigned int timeout_ms);

接口说明

从指定DTLS连接中读取数据, 此接口为同步接口, 在超前前读取到数据则立即返回, 否则在超时时间到

时才解除阻塞并返回

562 文档版本:20200417

Page 575: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

参数说明

参数 数据类型 方向 说明

context DTLSContext * 输入 DTLS会话句柄

p_data unsigned char * 输出 指向接收缓冲区的指针

p_datalen unsigned int * 输出 指向接收数据长度变量的指针

timeout_ms unsigned int 输入 超时时间

返回值说明

值 说明

0 操作成功

> 0 操作错误码

HAL_DTLSSession_write

原型

unsigned int HAL_DTLSSession_write(DTLSContext *context, const unsigned char *p_data, unsigned int *p_datalen);

接口说明

向指定DTLS连接写入数据

参数说明

参数 数据类型 方向 说明

context DTLSContext * 输入 DTLS会话句柄

p_data unsigned char * 输入 指向发送数据缓冲区的指针

p_datalen unsigned int * 输入 指向发送数据长度变量的指针, 用于指定发送字节长度

返回值说明

值 说明

0 操作成功

文档版本:20200417 563

Page 576: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

值 说明

> 0 操作错误码

HAL_UDP_close_without_connect

原型

int HAL_UDP_close_without_connect(intptr_t sockfd)

接口说明

销毁sockfd指定的UDP socket,释放资源

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 UDP socket句柄

返回值说明

值 说明

< 0 操作失败

= 0 操作成功

HAL_UDP_create

原型

intptr_t HAL_UDP_create(_IN_ char *host, _IN_ unsigned short port);

接口说明

建立指定目的地址和目的端口的UDP连接

参数说明

参数 数据类型 方向 说明

host const char * 输入 UDP目的地址

port unsigned short 输入 UDP目的端口

564 文档版本:20200417

Page 577: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

返回值说明

值 说明

< 0 创建失败

>= 0 创建成功, 返回值为UDP socket句柄

HAL_UDP_read

原型

int HAL_UDP_read( _IN_ intptr_t p_socket, _OU_ unsigned char *p_data, _OU_ unsigned int datalen);

接口说明

从指定UDP连接中读取数据, 此接口为阻塞接口

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 指定用来发送组播请求的UDP socket

p_group char * 输入 指定要加入的组播组名称

返回值说明

值 说明

< 0 UDP连接出现错误

= 0 发送成功

> 0 读取到的数据字节数

HAL_UDP_readTimeout

原型

int HAL_UDP_readTimeout( _IN_ intptr_t p_socket, _OU_ unsigned char *p_data, _IN_ unsigned int datalen, _IN_ unsigned int timeout_ms);

文档版本:20200417 565

Page 578: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

从指定的UDP句柄读取指定长度数据到缓冲区, 阻塞时间不超过指定时长, 若读取到指定长度数据完需

立即返回, 调用该接口之前需要调用HAL_UDP_connect()设置好源地址和端口

参数说明

返回值说明

HAL_UDP_recv

原型

int HAL_UDP_recv(_IN_ intptr_t sockfd, _OU_ unsigned char *p_data, _IN_ unsigned int datalen, _IN_ unsigned int timeout_ms);

接口说明

从指定的UDP句柄接收指定长度数据到缓冲区, 阻塞时间不超过指定时长, 且指定长度若接收完需提前

返回, 调用该接口之前需要调用HAL_UDP_connect()设置好源地址和端口

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 UDP socket句柄

p_data unsigned char * 输出 指向数据接收缓冲区的指针

datalen unsigned int 输入 接收缓冲区的字节大小

timeout_ms unsigned int 输入 阻塞的超时时间, 单位ms

返回值说明

值 说明

< 0 接收过程中出现错误或异常

= 0 在指定的timeout_ms时间内, 没有接收到任何数据

> 0 在指定的timeout_ms时间内, 实际接收到的数据字节数

566 文档版本:20200417

Page 579: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

HAL_UDP_send

原型

int HAL_UDP_sendto(_IN_ intptr_t sockfd, _IN_ const NetworkAddr *p_remote, _IN_ const unsigned char *p_data, _IN_ unsigned int datalen, _IN_ unsigned int timeout_ms);

接口说明

向指定的UDP句柄发送指定缓冲区的指定长度, 阻塞时间不超过指定时长, 且指定长度若发送完需提前

返回, 调用该接口之前需要调用HAL_UDP_connect()设置好目的地址和端口

参数说明

参数 数据类型 方向 说明

sockfd intptr_t 输入 UDP socket句柄

p_data const unsigned char *

输入 指数据发送缓冲区的指针

datalen unsigned int 输入 待发送数据的字节长度

timeout_ms unsigned int 输入 阻塞的超时时间, 单位ms

返回值说明

值 说明

< 0 发送过程中出现错误或异常

= 0 在指定的timeout_ms时间内, 没有任何数据发送成功

> 0 在指定的timeout_ms时间内, 实际发送的数据字节数

HAL_UDP_write

原型

int HAL_UDP_write( _IN_ intptr_t p_socket, _IN_ const unsigned char *p_data, _IN_ unsigned int datalen);

文档版本:20200417 567

Page 580: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

接口说明

向指定UDP句柄写入指定字节长度的数据

参数说明

参数 数据类型 方向 说明

p_socket intptr_t 输入 用于标识连接的描述符

p_data const unsigned char *

输入 指向数据发送缓冲区的指针

datalen unsigned int 输入 待写入数据的字节长度

返回值说明

值 说明

< 0 UDP连接发生错误

= 0 EOF, 文件已结束

> 0 实际写入的字节数

1.2.2 Android SDK

1.2.2.1 工程配置您可以使用物联网平台提供的Android SDK,搭建设备与云端的双向数据通道。SDK包含设备动态注

册、初始化建联和数据上下行的接口等内容。

Android SDK提供Demo,供您参考使用。单击下载Android SDK Demo。下载本Demo将默认您同

意本软件许可协议。

配置

1. 在Android工程根目录下的build.gradle 基础配置文件中,加入阿里云仓库地址,进行仓库配

置。

allprojects { epositories { jcenter() google() // 阿里云仓库地址 maven { url "http://maven.aliyun.com/nexus/content/repositories/releases/" } maven { url "http://maven.aliyun.com/nexus/content/repositories/snapshots" }

568 文档版本:20200417

Page 581: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

} }

2. 在模块的 build.gradle 中,添加SDK的依赖,引入 SDK :iot-linkkit。

compile('com.aliyun.alink.linksdk:iot-linkkit:1.6.6')

混淆配置

# linkkit API -keep class com.aliyun.alink.**{*;} -keep class com.aliyun.linksdk.**{*;} -dontwarn com.aliyun.** -dontwarn com.alibaba.** -dontwarn com.alipay.** -dontwarn com.ut.** # keep native method -keepclasseswithmembernames class * { native <methods>; }

# keep netty -keepattributes Signature,InnerClasses -keepclasseswithmembers class io.netty.** { *; } -dontwarn io.netty.** -dontwarn sun.**

# keep mqtt -keep public class org.eclipse.paho.**{*;}

# keep fastjson -dontwarn com.alibaba.fastjson.** -keep class com.alibaba.fastjson.**{*;}

# keep gson -keep class com.google.gson.** { *;}

# keep network core -keep class com.http.**{*;}

# keep okhttp -dontwarn okhttp3.** -dontwarn okio.** -dontwarn javax.annotation.** -keep class okio.**{*;} -keep class okhttp3.**{*;} -keep class org.apache.commons.codec.**{*;}

1.2.2.2 认证与连接本文介绍如何进行 SDK 初始化,建立设备与云端的连接。

设备的身份认证支持三种方法,不同方法需填写不同信息。

• 使用三元组认证方式,需要用户为每个设备提供ProductKey、DeviceName和DeviceSecret。

• 使用动态注册认证方式,需要有ProductKey、ProductSecret和DeviceName,并在控制台开启

动态注册。

• 使用ID2认证方式

文档版本:20200417 569

Page 582: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

三元组认证方式

三元组认证方式指设备在出厂前已经为每个设备烧写了ProductKey、DeviceName、DeviceSecret

,注意每个设备的三元组不能一样,否则会出现一个设备上线导致另外一个设备下线的情况。

初始化代码如下所示:

/*** 设置设备三元组信息*/DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey;// 产品类型deviceInfo.deviceName = deviceName;// 设备名称deviceInfo.deviceSecret = deviceSecret;// 设备密钥

/*** 设置设备当前的初始状态值,属性需要和云端创建的物模型属性一致* 如果这里什么属性都不填,物模型就没有当前设备相关属性的初始值。* 用户调用物模型上报接口之后,物模型会有相关数据缓存。*/Map<String, ValueWrapper> propertyValues = new HashMap<>();// 示例// propertyValues.put("LightSwitch", new ValueWrapper.BooleanValueWrapper(0));

IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey,

deviceName, deviceSecret);LinkKitInitParams params = new LinkKitInitParams();params.deviceInfo = deviceInfo;params.propertyValues = propertyValues;params.mqttClientConfig = clientConfig;

/*** 设备初始化建联* onError 初始化建联失败,需要用户重试初始化。如因网络问题导致初始化失败。* onInitDone 初始化成功 */LinkKit.getInstance().init(context, params, new ILinkKitConnectListener() { @Override public void onError(AError error) { // 初始化失败 error包含初始化错误信息 }

@Override public void onInitDone(Object data) { // 初始化成功 data 作为预留参数 }});

动态注册

动态注册指设备出厂前烧写了ProductKey、ProductSecret以及DeviceName,其中DeviceName

是厂商指定的,通常为设备的MAC地址或者SN,由于设备即使不连接阿里云也需要烧写MAC地址或

者SN,所以使用动态注册方案对设备厂商的产线无需做更改,因为ProductKey、ProductSecret可

以在软件固件中进行指定。

570 文档版本:20200417

Page 583: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

动态注册将会从云端获取设备的DeviceSecret,然后仍然使用三元组认证方式与云端交互来进行设备

认证。所以__设备需要将收到的DeviceSecret持久化存储,确保设备进行OTA升级、配置清除之后仍

然存在。

动态初始化成功之后不能再执行动态初始化,后续应用重新启动(包括卸载后重装启动)都需要从持

久化存储中获取三元组,然后执行初始化建联(即三元组认证方式与云端建立连接)。

// ####### 一型一密动态注册接口开始 ###### /*** 注意:动态注册成功,设备上线之后,不能再次执行动态注册,云端会返回已注册错误信息。* 因此用户在编程时首先需要判断设备是否已获取过deviceSecret,没有获取过的情况下再* 调用动态注册接口去获取deviceSecret */DeviceInfo myDeviceInfo = new DeviceInfo();myDeviceInfo.productKey = productKey;myDeviceInfo.deviceName = deviceName;myDeviceInfo.productSecret = productSecret;LinkKitInitParams params = new LinkKitInitParams();params.deviceInfo = myDeviceInfo;

// 设置动态注册请求 path 和 域名,域名使用默认即可HubApiRequest hubApiRequest = new HubApiRequest();hubApiRequest.path = "/auth/register/device";LinkKit.getInstance().deviceRegister(context, params, hubApiRequest, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { // aRequest 用户的请求数据 if (aResponse != null && aResponse.data != null) { ResponseModel<Map<String, String>> response = JSONObject.parseObject(aResponse.data.toString(), new TypeReference<ResponseModel<Map<String, String>>>() { }.getType()); if ("200".equals(response.code) && response.data != null && response.data.containsKey("deviceSecret") && !TextUtils.isEmpty(response.data.get("deviceSecret"))) { eviceInfo.deviceSecret = response.data.get("deviceSecret"); // getDeviceSecret success, to build connection. // 持久化 deviceSecret 初始化建联的时候需要 // TODO 用户需要按照实际场景持久化设备的三元组信息,用于后续的连接 // 成功获取 deviceSecret,调用初始化接口建联 // TODO 调用设备初始化建联 } } }

@Override public void onFailure(ARequest aRequest, AError aError) { Log.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]"); }});// ####### 一型一密动态注册接口结束 ######

ID2设备认证

SDK初始化的时候添加以下设置。

/** * 云端创建使用 iTLS 认证方式的设备采用这种方式初始化

文档版本:20200417 571

Page 584: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

* 产品需要到 ID2 授权 */ IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret); clientConfig.channelHost = productKey + ".itls.cn-shanghai.aliyuncs.com:1883"; clientConfig.productSecret = productSecret; clientConfig.secureMode = 8; linkKitInitParams.mqttClientConfig = clientConfig;

SDK反初始化

如果需要注销初始化,调用如下接口。

// 取消注册 notifyListener,notifyListener对象需和注册的时候是同一个对象 LinkKit.getInstance().unRegisterOnPushListener(notifyListener); LinkKit.getInstance().deinit();

其他设置

• 日志开关

打开SDK内部日志输出开关:

ALog.setLevel(ALog.LEVEL_DEBUG);

• 连接状态监听

如果需要监听设备的上下线信息,云端下发的所有数据,可以设置以下监听器。

IConnectNotifyListener notifyListener = new IConnectNotifyListener() { @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // 云端下行数据回调 // connectId 连接类型 topic 下行 topic; aMessage 下行数据 //String pushData = new String((byte[]) aMessage.data); // pushData 示例 {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"} // method 服务类型; params 下推数据内容 } @Override public boolean shouldHandle(String connectId, String topic) { // 选择是否不处理某个 topic 的下行数据 // 如果不处理某个topic,则onNotify不会收到对应topic的下行数据 return true; //TODO 根基实际情况设置 } @Override public void onConnectStateChange(String connectId, ConnectState connectState) { // 对应连接类型的连接状态变化回调,具体连接状态参考 SDK ConnectState } } // 注册下行监听,包括长连接的状态和云端下行的数据

572 文档版本:20200417

Page 585: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

LinkKit.getInstance().registerOnPushListener(notifyListener);

• 请求域名

云端接口的请求域名,请参考地域和可用区查看支持的域名。

- MQTT域名设置 SDK初始化的时候添加以下设置。

// 设置 Mqtt 请求域名 LinkKitInitParams 初始化参数 IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret); // 慎用 设置 mqtt 请求域名,默认 productKey+".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883" ,如果无具体的业务需求,请不要设置。 //clientConfig.channelHost = "xxx"; linkKitInitParams.mqttClientConfig = clientConfig;

- 一型一密域名设置 SDK动态注册的时候添加以下设置。

HubApiRequest hubApiRequest = new HubApiRequest(); // 一型一密域名 默认"iot-auth.cn-shanghai.aliyuncs.com" // hubApiRequest.domain = "xxx"; // 如无特殊需求,不要设置 hubApiRequest.path = "/auth/register/device";

• Mqtt 连接参数

- 设置Mqtt Keep-Alive 时间

// interval 单位秒 MqttConfigure.setKeepAliveInterval(int interval);

- qos设置

MqttPublishRequest request = new MqttPublishRequest();

// 支持 0 和 1, 默认0 request.qos = 0; request.isRPC = false; request.topic = topic.replace("request", "response"); String resId = topic.substring(topic.indexOf("rrpc/request/")+13); request.msgId = resId;

// TODO 用户根据实际情况填写 仅做参考 request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }"; >

- cleanSession 设置

IoTMqttClientConfig clientConfig = new IoTMqttClientConfig(productKey, deviceName, deviceSecret); // 对应 receiveOfflineMsg = !cleanSession, 默认不接受离线消息 clientConfig.receiveOfflineMsg = true;

1.2.2.3 物模型开发设备可以使用物模型功能,实现属性上报(如上报设备状态)、事件上报(上报设备异常或错误)和

服务调用(通过云端调用设备提供的服务)。

getDeviceThing()返回的IThing接口介绍请参见 IThing ApiReference。

文档版本:20200417 573

Page 586: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

设备属性

• 设备属性上报

// 设备上报Map<String, ValueWrapper> reportData = new HashMap<>();// identifier 是云端定义的属性的唯一标识,valueWrapper是属性的值// reportData.put(identifier, valueWrapper); // 参考示例,更多使用可参考demo LinkKit.getInstance().getDeviceThing().thingPropertyPost(reportData, new IPublishResourceListener() { @Override public void onSuccess(String resID, Object o) { // 属性上报成功 resID 设备属性对应的唯一标识 }

@Override public void onError(String resId, AError aError) { // 属性上报失败 }});

• 设备属性获取

// 根据 identifier 获取当前物模型中该属性的值String identifier = "xxx";LinkKit.getInstance().getDeviceThing().getPropertyValue(identifier);

// 获取所有属性LinkKit.getInstance().getDeviceThing().getProperties()

设备事件

设备事件上报

HashMap<String, ValueWrapper> hashMap = new HashMap<>();// TODO 用户根据实际情况设置// hashMap.put("ErrorCode", new ValueWrapper.IntValueWrapper(0));OutputParams params = new OutputParams(hashMap);LinkKit.getInstance().getDeviceThing().thingEventPost(identifier, params, new IPublishResourceListener() { @Override public void onSuccess(String resId, Object o) { // 事件上报成功 }

@Override public void onError(String resId, AError aError) { // 事件上报失败 }});

设备服务

• 设备服务获取 Service 定义参见 Service API Reference。

// 获取设备支持的所有服务LinkKit.getInstance().getDeviceThing().getServices()

574 文档版本:20200417

Page 587: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

• 设备服务调用监听 云端在添加设备服务时,需设置该服务的调用方式,由Service中的callType

字段表示。同步服务调用时callType="sync";异步服务调用callType="async"。设备属性设置和

获取也是通过服务调用监听方式实现云端服务的下发。

- 异步服务调用 设备先注册服务的处理监听器,当云端触发异步服务调用的时候,下行的请

求会到注册的监听器中。一个设备会有多种服务,通常需要注册所有服务的处理监听器。

onProcess 是设备收到的云端下行的服务调用,第一个参数是需要调用服务对应的 identifier

,用户可以根据 identifier (identifier 是云端在创建属性或事件或服务的时候的标识符,可以

在云端产品的功能定义找到每个属性或事件或服务对应的identifier)做不同的处理。云端调用

设置服务的时候,设备需要在收到设置指令后,调用设备执行真实操作,操作结束后上报一条

属性状态变化的通知。

// 用户可以根据实际情况注册自己需要的服务的监听器LinkKit.getInstance().getDeviceThing().setServiceHandler(service.getIdentifier(), mCommonHandler);// 服务处理的handlerprivate ITResRequestHandler mCommonHandler = new ITResRequestHandler() { @Override public void onProcess(String identify, Object result, ITResResponseCallback itResResponseCallback) { // 收到云端异步服务调用 identify 设备端属性或服务唯一标识 result 下行服务调用数据 // iotResResponseCallback 用户处理完服务调用之后响应云端 具体使用参见 Demo 代码 try { if (SERVICE_SET.equals(identify)) { // set 异步服务调用 // TODO 用户按照真实设备的接口调用 设置设备的属性 // 设置完真实设备属性之后,上报设置完成的属性值 // 用户根据实际情况判断属性是否设置成功 这里测试直接返回成功 boolean isSetPropertySuccess = true; if (isSetPropertySuccess){ if (result instanceof InputParams) { Map<String, ValueWrapper> data = (Map<String, ValueWrapper>) ((InputParams) result).getData(); // 响应云端 接收数据成功 itResResponseCallback.onComplete(identify, null, null); } else { itResResponseCallback.onComplete(identify, null, null); } } else { AError error = new AError(); error.setCode(100); error.setMsg("setPropertyFailed."); itResResponseCallback.onComplete(identify, new ErrorInfo(error), null); }

} else if (SERVICE_GET.equals(identify)){ // get异步服务调用 // 初始化的时候将默认值初始化传进来,物模型内部会直接返回云端缓存的值

} else { // 用户定义服务调用 // 根据不同的服务做不同的处理,跟具体的服务有关系 OutputParams outputParams = new OutputParams();// outputParams.put("op", new ValueWrapper.IntValueWrapper(20)); itResResponseCallback.onComplete(identify,null, outputParams);

文档版本:20200417 575

Page 588: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

} } catch (Exception e) { e.printStackTrace(); } }

@Override public void onSuccess(Object o, OutputParams outputParams) { // 服务注册成功 tag:用户传入的tag,未使用到 outputParams:异步回调成功的返回数据,outparams等类型 }

@Override public void onFail(Object o, ErrorInfo errorInfo) { // 服务注册失败 }};

- 同步服务调用 同步服务调用是一个 RRPC 调用。用户可以注册一个下行数据监听,当云端触发

服务调用时,可以在 onNotify 收到云端的下行服务调用。收到云端的下行服务调用之后,用

户根据实际服务调用对设备做服务处理,处理之后需要回复云端的请求,即发布一个带有处理

结果的请求到云端。当前版本添加了支持使用自定义RRPC,云端的同步服务属性下行将走自

定义RRPC通道下行,用户在升级SDK之后要注意这个改动点。

if (CONNECT_ID.equals(connectId) && !TextUtils.isEmpty(topic) && topic.startsWith("/ext/rrpc/")) { showToast("收到云端自定义RRPC下行");// ALog.d(TAG, "receice Message=" + new String((byte[]) aMessage.data)); // 服务端返回数据示例 {"method":"thing.service.test_service","id":"123374967","params":{"vv":60},"version":"1.0.0"} MqttPublishRequest request = new MqttPublishRequest(); // 支持 0 和 1, 默认0// request.qos = 0; request.isRPC = false; request.topic = topic.replace("request", "response"); String[] array = topic.split("/"); String resId = array[3]; request.msgId = resId; // TODO 用户根据实际情况填写 仅做参考 request.payloadObj = "{\"id\":\"" + resId + "\", \"code\":\"200\"" + ",\"data\":{} }";// aResponse.data = LinkKit.getInstance().publish(request, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { Log.d(TAG, "onResponse() called with: aRequest = [" + aRequest + "], aResponse = [" + aResponse + "]"); }

@Override public void onFailure(ARequest aRequest, AError aError) { Log.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]"); } });}

576 文档版本:20200417

Page 589: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.2.4 自定义MQTT Topic通信Android SDK 提供了与云端长链接的基础能力接口,用户可以直接使用这些接口完成自定义 Topic

相关的功能。提供的基础能力包括:发布、订阅、取消订阅、RRPC、订阅下行。如果不想使用物模

型,可以通过这部分接口实现云端数据的上下行。

调用上行请求接口,SDK封装了上行发布、订阅和取消订阅等接口。

/** * 发布 * * @param request 发布请求 * @param listener 监听器 */ void publish(ARequest request, IConnectSendListener listener);

/** * 订阅 * * @param request 订阅请求 * @param listener 监听器 */ void subscribe(ARequest request, IConnectSubscribeListener listener);

/** * 取消订阅 * * @param request 取消订阅请求 * @param listener 监听器 */ void unsubscribe(ARequest request, IConnectUnscribeListener listener);

调用示例: QoS 设置可以参照该示例进行设置。

// 发布 MqttPublishRequest request = new MqttPublishRequest(); request.isRPC = false; // topic 替换成用户自己需要发布的 topic request.topic = topic;

// 设置 qos request.qos = 0; // data 替换成用户需要发布的数据 request.payloadObj = data; LinkKit.getInstance().publish(request, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) {

// 发布成功 } @Override public void onFailure(ARequest aRequest, AError aError) {

// 发布失败 } });

// 订阅 MqttSubscribeRequest subscribeRequest = new MqttSubscribeRequest();

文档版本:20200417 577

Page 590: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

// subTopic 替换成用户自己需要订阅的

topic subscribeRequest.topic = subTopic; subscribeRequest.isSubscribe = true; LinkKit.getInstance().subscribe(subscribeRequest, new IConnectSubscribeListener() { @Override public void onSuccess() {

// 订阅成功 } @Override public void onFailure(AError aError) {

// 订阅失败 } });

// 取消订阅 MqttSubscribeRequest unsubRequest = new MqttSubscribeRequest();

// unSubTopic 替换成用户自己需要取消订阅的 topic unsubRequest.topic = unSubTopic; unsubRequest.isSubscribe = false; LinkKit.getInstance().unsubscribe(unsubRequest, new IConnectUnscribeListener() { @Override public void onSuccess() {

// 取消订阅成功 } @Override public void onFailure(AError aError) {

// 取消订阅失败 } });

下行数据监听

下行数据监听可以通过 RRPC 方式或者注册一个下行数据监听器实现。

/** * RRPC 接口 * * @param request RRPC 请求 * @param listener 监听器 */ void subscribeRRPC(ARequest request, IConnectRrpcListener listener);

/** * 注册下行数据监听器 * * @param listener 监听器 */ void registerOnPushListener(IConnectNotifyListener listener);

/** * 取消注册下行监听器 * * @param listener 监听器 */

578 文档版本:20200417

Page 591: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

void unRegisterOnPushListener(IConnectNotifyListener listener);

调用示例(数据监听):

// 下行数据监听 IConnectNotifyListener onPushListener = new IConnectNotifyListener() { @Override public void onNotify(String connectId, String topic, AMessage aMessage) { // 下行数据通知 }

@Override public boolean shouldHandle(String connectId, String topic) { return true; // 是否需要处理 该 topic }

@Override public void onConnectStateChange(String connectId, ConnectState connectState) { // 连接状态变化 } }; // 注册 LinkKit.getInstance().registerOnPushListener(onPushListener); // 取消注册 LinkKit.getInstance().unRegisterOnPushListener(onPushListener);

调用示例(RRPC):

final MqttRrpcRegisterRequest registerRequest = new MqttRrpcRegisterRequest(); // rrpcTopic 替换成用户自己自定义的 RRPC topic registerRequest.topic = rrpcTopic; // rrpcReplyTopic 替换成用户自己定义的RRPC 响应 topic registerRequest.replyTopic = rrpcReplyTopic; // 根据需要填写,一般不填 // registerRequest.payloadObj = payload; // 先订阅 rrpcTopic // 云端发布消息到 rrpcTopic // 收到下行数据 回复云端(rrpcReplyTopic) 具体可参考 Demo 同步服务调用 LinkKit.getInstance().subscribeRRPC(registerRequest, new IConnectRrpcListener() { @Override public void onSubscribeSuccess(ARequest aRequest) { // 订阅成功 }

@Override public void onSubscribeFailed(ARequest aRequest, AError aError) { // 订阅失败 }

@Override public void onReceived(ARequest aRequest, IConnectRrpcHandle iConnectRrpcHandle) { // 收到云端下行 // 响应获取成功 if (iConnectRrpcHandle != null){ AResponse aResponse = new AResponse(); // 仅供参考,具体返回云端的数据用户根据实际场景添加到data结构体 aResponse.data = "{\"id\":\"" + 123 + "\", \"code\":\"200\"" + ",\"data\":{} }"; iConnectRrpcHandle.onRrpcResponse(registerRequest.replyTopic, aResponse); } }

文档版本:20200417 579

Page 592: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

@Override public void onResponseSuccess(ARequest aRequest) { // RRPC 响应成功 }

@Override public void onResponseFailed(ARequest aRequest, AError aError) { // RRPC 响应失败 } });

1.2.2.5 远程配置远程配置可以用于更新设备的配置信息,包括设备的系统参数、网络参数或者本地策略等等。

使用该功能前,需在云端开启产品的远程配置功能。

远程配置相关接口参见设备 IDeviceCOTA。

主动获取配置

String COTA_get = "{" + " \"id\": 123," + " \"version\": \"1.0\"," + " \"params\": {" + "\"configScope\": \"product\"," + "\"getType\": \"file\"" + " }," + " \"method\": \"thing.config.get\"" + "}";

RequestModel<Map> requestModel = JSONObject.parseObject(COTA_get, new TypeReference<RequestModel<Map>>() { }.getType());LinkKit.getInstance().getDeviceCOTA().COTAGet(requestModel, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { // 获取远程配置结果成功 }

@Override public void onFailure(ARequest aRequest, AError aError) { // 获取远程配置失败 }});

订阅获取

设备端可以通过订阅获取远程配置信息。

// 注意:云端目前有做限制,一个小时只能全品类下发一次 COTA 更新LinkKit.getInstance().getDeviceCOTA().setCOTAChangeListener(new IConnectRrpcListener() { @Override public void onSubscribeSuccess(ARequest aRequest) { // 订阅成功 }

@Override public void onSubscribeFailed(ARequest aRequest, AError aError) { // 订阅失败 }

@Override

580 文档版本:20200417

Page 593: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

public void onReceived(ARequest aRequest, IConnectRrpcHandle iConnectRrpcHandle) { // 接收到远程配置下行数据 if (aRequest instanceof MqttRrpcRequest){ // 云端下行数据 返回数据示例参见 Demo // ((MqttRrpcRequest) aRequest).payloadObj; } }

@Override public void onResponseSuccess(ARequest aRequest) { // 回复远程配置成功 }

@Override public void onResponseFailed(ARequest aRequest, AError aError) { // 回复远程配置失败 }});

1.2.2.6 设备OTA开发介绍设备OTA开发的基本流程及接入的方法。

OTA基本流程

1. 设备上报版本号

2. 设备订阅 OTA 相关topic

3. 在 OTA 后台配置 OTA 任务,可以按多纬度知道要升级的设备,地址:https://iot.console.

aliyun.com/product

4. 成功订阅了 OTA 相关topic的设备在当前配置的 OTA 任务中,设备会收到一个推送信息,其中包

括:

a. 可升级的版本号

b. 固件地址,大小,MD5

5. 下载固件,开始升级,并上报升级进度

6. 升级完成后,自动上报新的版本号,整个 OTA 流程结束

如何接入

1. 在后台配置 OTA 升级任务,获取 OTA 实例:

mOta = LinkKit.getInstance().getOta()

2. 准备OTA升级任务,目前自动完成版本上报,订阅 topic, 当有 ota 推送时,会通过IOta.

STEP_RCVD_OTA 回调:

mOta.tryStartOta(mConfig, new OtaListener(){ public boolean onOtaProgress(int step, IOta.OtaResult otaResult) { int code = otaResult.getErrorCode();

文档版本:20200417 581

Page 594: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

Object data = otaResult.getData(); switch (step) { case IOta.STEP_REPORT_VERSION: // 上报版本 break; case IOta.STEP_SUBSCRIBE: // 订阅回调 break;

case IOta.STEP_RCVD_OTA: // 有新的OTA固件,返回true 表示继续升级 break; case IOta.STEP_DOWNLOAD: // 下载固件中 break; }

return true; }});

3. 收到推送的OTA 时,返回true ,会自动下载固件,下载进度通过IOta.STEP_DOWNLOAD 回调

4. 固件下载完成后,设备厂商通过自己的OTA 方式升级设备即可

注意:

本SDK只提供固件的管理、推送、下载,具体OTA进度需要开发者者自己定义,通过接口

reportProgress()完成,同时SDK提供接口reportVersion()用于上报版本功能。

1.2.2.7 标签支持设备端上报标签到云端,以及删除设备标签。

设备标签相关接口参见设备 IDeviceLabel。

上报标签

// 标签是 key,value的形式 可以替换 attrKey 和 attrValueString update_label = "{" + " \"id\": \"123\"," + " \"version\": \"1.0\"," + " \"params\": [" + " {" + " \"attrKey\": \"Temperature\"," + " \"attrValue\": \"36.8\"" + " }" + " ]," + " \"method\": \"thing.deviceinfo.update\"" + "}";RequestModel<List<Map>> requestModel = JSONObject.parseObject(update_label, new TypeReference<RequestModel<List<Map>>>() {}.getType());LinkKit.getInstance().getDeviceLabel().labelUpdate(requestModel, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { // 更新标签成功 }

@Override public void onFailure(ARequest aRequest, AError aError) { // 更新标签失败 }});

582 文档版本:20200417

Page 595: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

删除标签

// 标签是 key,value的形式 可以替换 attrKey 和 attrValueString deleteLabel = "{" + " \"id\": \"123\"," + " \"version\": \"1.0\"," + " \"params\": [" + " {" + " \"attrKey\": \"Temperature\"" + " }" + " ]," + " \"method\": \"thing.deviceinfo.delete\"" + "}";RequestModel<List<Map>> requestModel = JSONObject.parseObject(deleteLabel, new TypeReference<RequestModel<List<Map>>>() {}.getType());LinkKit.getInstance().getDeviceLabel().labelDelete(requestModel, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { // 删除标签成功 }

@Override public void onFailure(ARequest aRequest, AError aError) { // 删除标签失败 }});

1.2.2.8 子设备管理如果当前设备是一个网关,且该网关下的子设备需接入云端,此时需要使用子设备管理功能。

网关子设备管理提供了子设备动态注册、获取云端网关下子设备列表、添加子设备、删除子设备、子

设备上线、子设备下线、监听子设备禁用和删除、代理子设备上下行的能力。

网关本身是一个直连设备可直接使用上述介绍的所有能力。网关和子设备之间的连接、数据通信需要

用户处理。

网关子设备管理相关接口参见设备IGateway

设备每次初始建联的时候都需要调用添加、登录接口。

网关开发过程说明

• 厂商在物联网平台定义网关产品(基础版或者高级版),设置“节点类型”为“网关”,设置网

关的身份认证模式,并根据网关功能定义topic或者定义物模型,并参照前面的章节中的说明对网

关自身的功能进行开发;

• 实现子设备的管理功能

1. 实现子设备的发现与连接功能,该部分功能由厂商自行实现,阿里并未提供网关如何发现以及

如何将子设备连接到网关的代码实现

2. 实现子设备三元组的获取方式,下面的内容有介绍几种获取子设备三元组的方式供厂商参考

3. 当网关发现并将一个子设备连接到网关后,如果需要该子设备能够通过物联网平台进行远程管

理,需要调用SDK的添加子设备接口将其告知物联网平台,添加之前需要先获得该子设备的三

文档版本:20200417 583

Page 596: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

元组信息;然后调用SDK提供的子设备上线接口通知物联网平台,因为如果一个子设备处于离

线状态,如果远程对子设备进行控制,物联网平台将直接返回失败、而不是将命令发送给网关

之后等待错误提示或者超时提示

4. 当网关告知物联网平台一个子设备上线之后,需要将子设备的状态信息上报云端以保证子设备

在云端的状态与当前子设备的状态一致。特别是使用物模型定义子设备功能时,子设备上线需

要将属性的最新数值通知云端;

5. 当网关的一个已添加到物联网平台的子设备离线时,网关需要调用子设备离线接口告知物联网

平台这个子设备已离线;

6. 当一个在线子设备的属性发生变化时,也需要实时告知物联网平台

7. 当网关离线并再次上线时(例如网络连接断开,或者网关重启),网关需要对所有已添加到云

端的子设备再次调用添加子设备接口,再次调用子设备上线接口,如果网关不知道子设备的属

性与网关离线前上报到云端的是否一致,那么网关需要将子设备的最新属性再次上报云端。

8. 当网关接收到来自物联网平台对子设备的控制消息时,网关如何将该消息转换成子设备识别的

格式并发送给子设备,由网关厂商进行实现

子设备开发过程

• 设备厂商在物联网平台定义子设备产品(基础版或者高级版),设置“节点类型”为“设

备”,设置产品的身份认证模式

• 阿里并不在子设备上提供任何SDK,因此网关如何发现子设备、如何连接子设备、网关如何发现

子设备上线或者离线、网关如何将来自物联网平台的命令发送给子设备,均由网关厂商与子设备

厂商定义协议并实现

子设备三元组的获取方式

子设备是通过网关到阿里云物联网进行注册的,注册时也需要使用到子设备的三元组进行设备验证。

下面是网关获取子设备三元组的几种方式,网关厂家根据自己的实际情况进行选用:

• 网关从子设备获取子设备三元组

由网关与子设备之间定义一套协议,当网关发现与连接子设备之后,获取到子设备的三元组。阿

里云并不提供参考协议实现,该协议由网关厂商与子设备厂商自行定义与实现。

• 网关预置子设备的三元组

如果网关设备预先可以得知自己需要连接的子设备,并且网关提供了某种配置方式输入子设备的

三元组信息,那么可以通过这种方式获取子设备的三元组。同样,该功能由网关厂商实现。

• 网关通过动态注册获取子设备三元组

网关可以通过某种协议发现与连接子设备,并获取到子设备的型号(model)以及唯一标识(例

如SN、MAC地址),但是并不知道子设备的DeviceSecret。由于子设备也需要在阿里云物联网平

584 文档版本:20200417

Page 597: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

台进行产品定义(云端会为子设备生成ProductKey),网关可以建立子设备型号(model)到阿

里云物联网平台ProductKey的映射(网关厂家在网关上实现该映射),并将设备的唯一标识作为

阿里云物联网平台的DeviceName,然后通过阿里云物联网平台提供的动态注册功能从云端获取

子设备的DeviceSecret,从而得到完整的子设备的三元组信息。

子设备动态注册

• 使用PK&DN动态注册

需要在云端开启允许动态注册功能,可以同时注册多个,用于获取子设备三元组。子设备添加到

网关之前需要先进行动态注册获取子设备三元组信息,如果本地已有子设备三元组信息,可以跳

过这一步。如果子设备已经被绑定到其他网关设备,动态注册不会返回该子设备的三元组信息。

LinkKit.getInstance().getGateway().gatewaySubDevicRegister(getSubDevList(), new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { ALog.d(TAG, "onResponse() called with: aRequest = [" + aRequest + "], aResponse = [" + (aResponse == null ? "null" : aResponse.data) + "]"); try { // 子设备动态注册成功 ResponseModel<List<DeviceInfo>> response = JSONObject.parseObject(aResponse.data.toString(), new TypeReference<ResponseModel<List<DeviceInfo>>>() { }.getType()); // 根据 response 的数据判断是否成功 code=200 //TODO 保存子设备的三元组信息 } catch (Exception e) { e.printStackTrace(); } }

@Override public void onFailure(ARequest aRequest, AError aError) { // 子设备动态注册失败 }});

• 使用PK&DN&PS动态注册

此动态注册方式涉及到子设备的pk需要预先获取,安全性会低于第一种动态注册方式。如果当前

已经有子设备的productKey、deviceName、productSecret信息,并且需要进行抢占式动态注

册,则可以使用 这种方式进行子设备动态注册。抢占式动态注册,即被其它网关设备绑定的子设

备三元组也会返回。推荐通过云端远程配置下发(COTA)下发子设备的PK、DN、PS信息到网关

设备,然后再进行抢占式动态注册。

应用场景:需要将子设备从A网关绑定到B网关的场景,如根据信号强度切换网关。使用PK&DN实

现的话需要子设备先在A网关登出,解除拓扑关系,然后与B建立拓扑关系。

// 该动态注册方案需要提前知道子设备的productSecret,安全性会比下面一种子设备动态注册低一点// 这种动态注册方式可以考虑和COTA-远程配置下发配合使用,在云端下发子设备的pk、dn、ps,网关收到后

文档版本:20200417 585

Page 598: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

// 完成动态注册// 使用于需要抢占绑定关系时使用,会返回被其他网关设备的子设备MqttPublishRequest request = new MqttPublishRequest();final RequestModel requestModel = new RequestModel();requestModel.id = String.valueOf(IDGenerater.generateId());requestModel.version = "1.0";requestModel.method = GatewayChannel.METHOD_PRESET_SUBDEV_REGITER;request.isRPC = true;JSONObject jsonObject = new JSONObject();JSONArray jsonArray = new JSONArray();for (int i = 0; i < presetSubdevList.size(); i++) { DeviceInfo itemDev = presetSubdevList.get(i); Map<String, String> itemMap = new HashMap<>(); itemMap.put("productKey", itemDev.productKey); itemMap.put("deviceName", itemDev.deviceName); itemMap.put("random", RandomStringUtil.getRandomString(10)); String sign = SignUtils.hmacSign(itemMap, itemDev.productSecret); itemMap.put("sign", sign); itemMap.put("signMethod", "hmacsha1"); jsonArray.add(itemMap);}

jsonObject.put("proxieds", jsonArray);requestModel.params = jsonObject;request.payloadObj = requestModel.toString();LinkKit.getInstance().getGateway().subDevicRegister(request, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { ALog.d(TAG, "onResponse() called with: aRequest = [" + aRequest + "], aResponse = [" + aResponse + "]"); try { showToast("收到子设备动态结果"); ResponseModel<Map<String, List<DeviceInfo>>> responseModel = JSONObject.parseObject(aResponse.data.toString(), new TypeReference<ResponseModel<Map<String, List<DeviceInfo>>>>() { }.getType()); // TODO 保存子设备的三元组信息 ALog.d(TAG, "onResponse responseModel=" + JSONObject.toJSONString(responseModel)); // {"code":200,"data":{"failures":[],"successes":[{"deviceSecret":"xxx","productKey":"xxx","deviceName":"xxx"}]},"id":"1","message":"success","method":"thing.proxy.provisioning.product_register","version":"1.0"} // 动态注册成功列表 List<DeviceInfo> successList = responseModel.data.get("successes"); // 动态注册失败列表 List<DeviceInfo> failList = responseModel.data.get("failures"); } catch (Exception e) { e.printStackTrace(); } }

@Override public void onFailure(ARequest aRequest, AError aError) { ALog.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]"); }});

586 文档版本:20200417

Page 599: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

获取子设备列表

获取网关当前在云端已经有哪些子设备。

LinkKit.getInstance().getGateway().gatewayGetSubDevices(new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { // 获取子设备列表结果 try { ResponseModel<List<DeviceInfo>> response = JSONObject.parseObject(aResponse.data.toString(), new TypeReference<ResponseModel<List<DeviceInfo>>>() { }.getType()); // TODO 根据实际应用场景处理 } catch (Exception e) { e.printStackTrace(); }}

@Override public void onFailure(ARequest aRequest, AError aError) { // 获取子设备列表失败 }});

添加子设备

子设备动态注册完成之后,可以通过该接口将子设备添加到网关下。

final DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey; // 三元组 产品型号(必填)deviceInfo.deviceName = deviceName; // 三元组 设备标识 (必填)LinkKit.getInstance().getGateway().gatewayAddSubDevice(deviceinfo, new ISubDeviceConnectListener() { @Override public String getSignMethod() { // 使用的签名方法 return "hmacsha1"; }

@Override public String getSignValue() { // 获取签名,用户使用 deviceSecret 获得签名结果 Map<String, String> signMap = new HashMap<>(); signMap.put("productKey", info.productKey); signMap.put("deviceName", info.deviceName);// signMap.put("timestamp", String.valueOf(System.currentTimeMillis())); signMap.put("clientId", getClientId()); return SignUtils.hmacSign(signMap, info.deviceSecret); }

@Override public String getClientId() { // clientId 可为任意值 return "id"; }

@Override

文档版本:20200417 587

Page 600: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

public void onConnectResult(boolean isSuccess, ISubDeviceChannel iSubDeviceChannel, AError aError) { // 添加结果 if (isSuccess) { // 子设备添加成功,接下来可以做子设备上线的逻辑 // subDevOnline(null); } }

@Override public void onDataPush(String s, AMessage message) { // 收到子设备下行数据 topic=" + s + ", data=" + message // 如禁用 删除 已经 设置、服务调用等 返回的数据message.data 是 byte[] }});

删除子设备

删除网关下的子设备。

final DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey; // 三元组 产品型号(必填)deviceInfo.deviceName = deviceName; // 三元组 设备标识 (必填)LinkKit.getInstance().getGateway().gatewayDeleteSubDevice(deviceinfo, new ISubDeviceRemoveListener() { @Override public void onSuceess() { // 成功删除子设备 删除之前可先做下线操作 }

@Override public void onFailed(AError aError) { // 删除子设备失败 }});

子设备上线

调用子设备上线之前,请确保已完成子设备添加。网关发现子设备连上网关之后,需要告知云端子设

备上线,子设备上线之后可以执行子设备的订阅、发布等操作。注意:由于接口调用都是异步的,子

设备上线接口不能在子设备添加的下一行调用,而是要放到子设备添加成功的回调里面调用。

final DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey; // 三元组 产品型号(必填)deviceInfo.deviceName = deviceName; // 三元组 设备标识 (必填)LinkKit.getInstance().getGateway().gatewaySubDeviceLogin(deviceinfo, new ISubDeviceActionListener() { @Override public void onSuccess() { // 代理子设备上线成功 // 上线之后可订阅 删除和禁用的下行通知 // subDevDisable(null); // subDevDelete(null); }

@Override public void onFailed(AError aError) {

588 文档版本:20200417

Page 601: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

ALog.d(TAG, "onFailed() called with: aError = [" + aError + "]"); }});

子设备下线

当子设备离线之后,网关需要告知云端子设备离线,以避免云端向子设备发送数据。子设备下线之后

不可以进行子设备的发布、订阅、取消订阅等操作。

final DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey; // 三元组 产品型号(必填)deviceInfo.deviceName = deviceName; // 三元组 设备标识 (必填)LinkKit.getInstance().getGateway().gatewaySubDeviceLogout(deviceinfo, new ISubDeviceActionListener() { @Override public void onSuccess() { // 代理子设备下线成功 }

@Override public void onFailed(AError aError) { // 代理子设备下线失败 }});

监听子设备禁用

网关设备可以在云端操作子设备,如禁用子设备、启用子设备、删除和子设备的拓扑关系。目前服务

端只支持禁用子设备的下行通知。服务端在禁用子设备的时候会对子设备做下线处理,后续网关将不

能代理子设备和云端做通信。

final DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey; // 三元组 产品型号(必填)deviceInfo.deviceName = deviceName; // 三元组 设备标识 (必填)LinkKit.getInstance().getGateway().gatewaySetSubDeviceDisableListener(deviceinfo, new IConnectRrpcListener() { @Override public void onSubscribeSuccess(ARequest aRequest) { // 订阅成功 }

@Override public void onSubscribeFailed(ARequest aRequest, AError aError) { // 订阅失败 }

@Override public void onReceived(ARequest aRequest, IConnectRrpcHandle iConnectRrpcHandle) { // 子设备禁用通知 iConnectRrpcHandle.onRrpcResponse(null, null); }

@Override public void onResponseSuccess(ARequest aRequest) { Log.d(TAG, "onResponseSuccess() called with: aRequest = [" + aRequest + "]"); }

文档版本:20200417 589

Page 602: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

@Override public void onResponseFailed(ARequest aRequest, AError aError) { Log.d(TAG, "onResponseFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]"); }});

代理子设备物模型上下行

• 子设备物模型初始化

子设备物模型初始化必须在子设备添加到网关下,且子设备已经登录的情况下才可以调用。

说明:

由于接口调用都是异步的,子设备物模型初始化接口不能在子设备登录的下一行调用,而是要放

到子设备登录成功的回调里面调用。

DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey;deviceInfo.deviceName = deviceName;// deviceInfo.deviceSecret = "xxxx";Map<String, ValueWrapper> subDevInitState = new HashMap<>();// subDevInitState.put(); //TODO 用户根据实际情况设置String tsl = null;// 用户根据实际情况设置,默认为空 直接从云端获取最细的 TSLLinkKit.getInstance().getGateway().initSubDeviceThing(tsl, deviceInfo, subDevInitState, new IDMCallback<InitResult>() { @Override public void onSuccess(InitResult initResult) { // 物模型初始化成功之后 可以做服务注册 上报等操作 }

@Override public void onFailure(AError aError) { // 子设备初始化失败 }});

• 子设备物模型使用接口使用和直连设备的物模型使用一致,获取 IThing 接口实现使用如下方式获

取。

// 获取 IThing 实例IThing thing = LinkKit.getInstance().getGateway().getSubDeviceThing(mBaseInfo).first;// thing 有可能为空,如子设备未登录、物模型未初始化、子设备未添加到网关、子设备处于离线状态等。// error 信息在 LinkKit.getInstance().getGateway().getSubDeviceThing(mBaseInfo).second 返回// 参考示例 注意判空thing.thingPropertyPost(reportData, new IPublishResourceListener() { @Override public void onSuccess(String s, Object o) { // 设备上报状态成功 }

@Override public void onError(String s, AError aError) {

590 文档版本:20200417

Page 603: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

// 设备上报状态失败 }});

• 子设备物模型销毁反初始化物模型,后续如果需要重新使用需要重新走登录、物模型初始化流

程。

LinkKit.getInstance().getGateway().uninitSubDeviceThing(mBaseInfo);

代理子设备基础上下行

使用网关的通道执行子设备的数据上下行。

final DeviceInfo deviceInfo = new DeviceInfo();deviceInfo.productKey = productKey; // 三元组 产品型号(必填)deviceInfo.deviceName = deviceName; // 三元组 设备标识 (必填)String topic = xxx;String publishData = xxx;// 订阅LinkKit.getInstance().getGateway().gatewaySubDeviceSubscribe(topic, deviceinfo, new ISubDeviceActionListener() { @Override public void onSuccess() { // 代理子设备订阅成功 }

@Override public void onFailed(AError aError) { // 代理子设备订阅失败 }});

//发布LinkKit.getInstance().getGateway().gatewaySubDevicePublish(topic, publishData, deviceinfo, new ISubDeviceActionListener() { @Override public void onSuccess() { // 代理子设备发布成功 }

@Override public void onFailed(AError aError) { // 代理子设备发布失败 }});

// 取消订阅LinkKit.getInstance().getGateway().gatewaySubDeviceUnsubscribe(topic, deviceinfo, new ISubDeviceActionListener() { @Override public void onSuccess() { // 代理子设备取消订阅成功 }

@Override public void onFailed(AError aError) { // 代理子设备取消订阅事变 }});

文档版本:20200417 591

Page 604: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

支持PermitJoin

如果网关是接入智能生活开放平台(又称飞燕平台),网关需要在收到来自云端的PermitJoin消息

时,再连接子设备、以及添加子设备。目前的版本还不支持对PermitJoin的封装(将在下一个迭代中

进行支持),可以通过下面的办法实现对PermitJoin消息的处理:

• 网关需要去发现并连接指定型号的子设备,如果网关找不到指定型号的子设备,那么就无需添加

子设备;添加子设备的接口见本章前面描述的“添加子设备”

• 如果网关收到PermitJoin之后,发现网关连接了多个指定型号的子设备,只向云端添加其中一个

子设备即可

@Overridepublic void onSubscribeFailed(ARequest aRequest, AError aError) { ALog.e(TAG, "onSubscribeFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");}

@Overridepublic void onReceived(ARequest aRequest, IConnectRrpcHandle iConnectRrpcHandle) { ALog.d(TAG, "onReceived() called with: aRequest = [" + aRequest + "], iConnectRrpcHandle = [" + iConnectRrpcHandle + "]"); showToast("接收到permitJoin指令"); // TODO user add sub device & if (aRequest instanceof MqttRrpcRequest){ // 云端下行数据 拿到 // ((MqttRrpcRequest) aRequest).payloadObj; // ResponseModel<Map<String, String>> responseModel = JSONObject.parseObject(((MqttRrpcRequest) aRequest).payloadObj, new TypeReference<ResponseModel<Map<String, String>>>(){}.getType()); // 返回数据示例 //{"id":"", //消息id

// 网关处理完子设备拓扑关系添加、登录后 if (iConnectRrpcHandle != null) { AResponse response = new AResponse(); // 回复示例 TODO edit by user // response.data 里的 id 字段需要与收到的 permitJoin 消息的 id 保持一致 response.data = "{\"id\":\"xxx\", \"code\":\"200\"" + ",\"data\":{} }"; iConnectRrpcHandle.onRrpcResponse(((MqttRrpcRequest) aRequest).replyTopic, response); } }}

@Overridepublic void onResponseSuccess(ARequest aRequest) { ALog.d(TAG, "onResponseSuccess() called with: aRequest = [" + aRequest + "]");}

@Overridepublic void onResponseFailed(ARequest aRequest, AError aError) { ALog.d(TAG, "onResponseFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");}

592 文档版本:20200417

Page 605: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.2.9 设备影子如果当前产品不具备物模型的能力,可以通过设备影子将当前设备的最新状态缓存到云端。云端缓存

的是一个最新的 JSON 格式数据,需要用户自己根据实际情况做解析。物模型具备更高级的设备影子

能力,能根据各个属性、事件、服务做独立展示,并具有所有操作的历史记录。

设备影子相关接口参见设备 IDeviceShadow

数据上行

• 获取云端设备影子

• 更新云端设备影子

• 删除云端设备影子

// 获取设备影子 具体业务可参考 DemoString data = "{" + "\"method\": \"get\"" + "}";// 更新设备影子 需要根据获得到的设备影子读取返回的 version值,在更新的时候 {ver} 替换为version+1// String data = "{" + "\"method\": \"update\"," + "\"state\": {" + "\"reported\": {" +// "\"color\": \"red\"" + "}" + "}," + "\"version\": {ver}" + "}";//删除设备影子 color 属性 {ver}需要替换// String data = "{" + "\"method\": \"delete\"," + "\"state\": {" + "\"reported\": {" +// "\"color\": \"null\"" + "}" + "}," + "\"version\": {ver}" + "}";LinkKit.getInstance().getDeviceShadow().shadowUpload(data, new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { // 设备影子更新成功 // 数据解析参考数据下行或 Demo }

@Override public void onFailure(ARequest aRequest, AError aError) { // 设备影子更新失败 }});

数据下行

监听云端设备影子数据更新,一般使用在 APP 去控制设备的时候。APP控制设备的时候,通过云端

下发设备影子更新到设备端,设备端拿到云端下行的设备影子之后,根据 desired 的值去执行设备更

新。

// 监听云端设备影子更新LinkKit.getInstance().getDeviceShadow().setShadowChangeListener(new IShadowRRPC() { @Override public void onSubscribeSuccess(ARequest aRequest) { // 订阅设备影子下行数据成功 }

文档版本:20200417 593

Page 606: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

@Override public void onSubscribeFailed(ARequest aRequest, AError aError) { // 订阅设备影子下行数据失败 }

@Override public void onReceived(ARequest aRequest, AResponse aResponse, IConnectRrpcHandle iConnectRrpcHandle) { // 接收到云端数据下行,下行数据在 aResponse 想里面 try { if (aRequest != null) { String dataStr = null; if (aResponse.data instanceof byte[]) { dataStr = new String((byte[]) aResponse.data, "UTF-8"); } else if (aResponse.data instanceof String) { dataStr = (String) aResponse.data; } else { dataStr = String.valueOf(aResponse.data); } // Log.d(TAG, "dataStr = " + dataStr); // 返回数据示例 //{"method":"control","payload":{"state":{"desired":{"mode":2,"color":"white"},"reported":{"mode":"1","color":"red"}},"metadata":{"desired":{"mode":{"timestamp":1547642408},"color":{"timestamp":1547642408}},"reported":{"mode":{"timestamp":1547642408},"color":{"timestamp":1547642408}}}},"timestamp":1547642408,"version":12} // 仅供参考 ShadowResponse<String> shadowResponse = JSONObject.parseObject(dataStr, new TypeReference<ShadowResponse<String>>() { }.getType()); if (shadowResponse != null && shadowResponse.version != null && TextUtils.isDigitsOnly(shadowResponse.version)) { version = Long.valueOf(shadowResponse.version); }

AResponse response = new AResponse(); // TODO 用户实现控制设备 // 用户控制设备之后 上报影子的值到云端 // 上报设置之后的值到云端 // 根据当前实际值上报 response.data = shadowUpdate.replace("{ver}", String.valueOf(version + 1)); // 第一个值 replyTopic 有默认值 用户不需要设置 iConnectRrpcHandle.onRrpcResponse(null, response); } } catch (Exception e) { e.printStackTrace(); } }

@Override public void onResponseSuccess(ARequest aRequest) { // 下行处理之后上报成功 }

@Override public void onResponseFailed(ARequest aRequest, AError aError) { // 下行处理之后上报失败 }});

594 文档版本:20200417

Page 607: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.2.10 HTTP2 流通道简介

HTTP 2流通到SDK提供流式数据接入。在一个连接上可以建立多个流通道,使用完流通到需要关闭流

通道。不同于视频流,该流通道较轻量级,可以快速打开关闭,适合较有限流数据传输,如文件上传

等。

1. 建立和云端的连接。

2. 发送数据流,可以一次性发完也可以多次发送完。

3. 发送数据流,可以一次性发完也可以多次发送完。

4. 发送方接收云端的响应,可以是一次响应完,也可以一直下推数据;5.流使用完需要关闭。

5. 流使用完需要关闭。

6. 不需要再使用 HTTP2 的时候需要关闭连接。

初始化

SDK 目前支持两种方式的流通道认证:设备接入认证、APP接入认证。IStreamSender 是 HTTP2 流

通道接口类。如果当前Android设备作为设备三元组接入,选择 设备认证初始化,如果是作为一个应

用只集成H2能力,则选择 APP接入初始化方式。

设备初始化

ioTH2Config.clientId = "client-id"; ioTH2Config.endPoint = "https://10.125.15.223:9999";

APP 初始化

Profile是 APP 认证方式初始化入口,作为设备的时候不需要走 APP 初始化。

/** * replace url appKey appSecret * url = "https://" * signMethod = AuthSignMethod.SHA1.getMethod();*/Profile profile = Profile.getAppKeyProfile("url", "appKey", new IAuthSign() { @Override public String getAuthSign(String signContent) { @Override public String getSignMethod() { return AuthSignMethod.SHA1.getMethod();// set bu user } // TODO by user // use appSecret to sign signContent and return signValue // hmacMd5Hex、hmacSha1Hex、hmacSha256Hex、hmacSha384Hex、hmacSha512Hex HmacUtils utils = new HmacUtils(HmacAlgorithms.HMAC_SHA_1, "appSecret"); return new String(Hex.encodeHex(utils.hmac(signContent))); }

文档版本:20200417 595

Page 608: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

});IStreamSender client = StreamSenderFactory.streamSender(profile);

流通道

• 建联

 CompletableListener是通用的异步回调接口。

@Overridepublic void completeExceptionally(Throwable throwable) {}

final Http2Request request = new Http2Request();// 添加请求参数// request.getHeaders().add("nothing", "ddd");client.openStream(serviceNme, request, new CompletableListener<Http2Response>() { @Override public void complete(Http2Response http2Response) { ALog.w(TAG, "open stream result: " + http2Response); // save dataStreamId of this stream if (http2Response != null) { dataStreamId = StreamUtil.getDataStreamId(http2Response.getHeaders()); } }

@Override public void completeExceptionally(Throwable throwable) { showToast("open Stream failed"); Log.w(TAG, "completeExceptionally: ", throwable); dataStreamOpened.set(false); }});

• 发送流

发送流需要使用到 openStream 返回的云端的 dataStreamId,以及需要发送的数据。一次

请求分多次发送可以有两种方式:一种是当做普通请求,每次发送header和部分数据,并设

置endStream为true;一种是第一次发送 header+data,后续只发送data。数据发送可以分为

以下几种(具体和业务服务端实现的功能有关):

- 一次请求,一次响应;类似 HTTP 1.1

- 一次请求,多次响应;数据下推

- 一次请求,分多次发送; |header+data | header+data| ... 或 | header + data |+ data|+

data|+...

IDownStreamListener 是下推数据流的数据接收接口。

@Override public void onDataRead(String s, byte[] bytes, boolean b) { ALog.d(TAG, "onDataRead() called with: s = [" + s + "], bytes = [" + new String(bytes) + "], b = [" + b + "]");

596 文档版本:20200417

Page 609: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

}

@Override public void onStreamError(String s, IOException e) { ALog.w(TAG, "onStreamError() called with: s = [" + s + "], e = [" + e + "]"); } }, new CompletableListener<StreamWriteContext>() { @Override public void complete(StreamWriteContext streamWriteContext) { ALog.d(TAG, "complete() called with: streamWriteContext = [" + streamWriteContext + "]"); }

@Override public void completeExceptionally(Throwable throwable) { ALog.w(TAG, "completeExceptionally() called with: throwable = [" + throwable + "]"); } });

Http2Request request = new Http2Request();request.setEndOfStream(true);client.closeStream(dataStreamId, request, new CompletableListener<Http2Response>() { @Override public void complete(Http2Response http2Response) { ALog.d(TAG, "complete() called with: http2Response = [" + http2Response + "]"); }

@Override public void completeExceptionally(Throwable throwable) { ALog.d(TAG, "completeExceptionally() called with: throwable = [" + throwable + "]"); }});

• 断连

@Overridepublic void completeExceptionally(Throwable throwable) {}

Http2Request request = new Http2Request();request.getHeaders().add("xxx", "xxx");client.upload(dataStreamId, filePath, request, new CompletableListener<Http2Response>() { @Override public void complete(Http2Response o) { ALog.d(TAG, "complete() called with: o = [" + o + "]"); // upload success }

@Override public void completeExceptionally(Throwable throwable) { ALog.w(TAG, "completeExceptionally() called with: throwable = [" + throwable + "]"); // upload fail }});

文档版本:20200417 597

Page 610: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

1.2.2.11 设备reset有的产品设计了reset按钮,用于清除设备上的配置,让设备恢复到出厂状态,这些功能由设备厂

商去实现。但是有的场景下,设备商需要云端感知设备上执行了reset操作,那么需要调用Link Kit

SDK提供的API告知云端。

Android设备只有用户主动触发reset调用的场景,例如单击按钮或者按键的时候开发者调

用SDK的reset接口reset调用之后,SDK分两个流程处理:

• 如果设备在线,调用reset接口到云端,成功之后销毁整个linkkit(调用deinit),失败按照流程2

处理。

• 如果设备不在线,设置一个reset的标志位,然后销毁整个linkkit,后续linkkit被重新初始化的时

候,根据是否有这个reset标志位在建联成功之后再调用reset接口,reset完成之后才会响应设备

的发现。如果APP卸载或删除APP数据之后,则下次启动则不再执行reset操作了,标志位被清除

LinkKit.getInstance().reset(new IConnectSendListener() { @Override public void onResponse(ARequest aRequest, AResponse aResponse) { ALog.d(TAG, "reset onResponse "); }

@Override public void onFailure(ARequest aRequest, AError aError) { ALog.d(TAG, "reset onFailure"); }});

智能生活开放平台的用户解绑操作

背景说明:

如果产品是在阿里云IoT的智能生活开放平台注册,那么用户只有通过手机APP与设备之间建立绑定

关系之后,才能对设备进行控制。如果设备被出售或者转让给了另外一个用户,那么新用户可以通过

触按reset按键告知云端解除设备与原用户的绑定关系,避免原用户对设备可以继续进行控制。

此时就需要调用LinkKit.getInstance().reset接口来告知云端解除设备与原有用户的绑定关系。

允许重新进行动态注册的操作

背景说明:

如果产品的认证选用了动态注册功能,设备出厂时只需要烧写ProductKey、ProductSecret,设备

连接到阿里云物联网时可以通过动态注册过程去获取设备的DeviceSecret;但是当设备获取到了

DeviceSecret之后,如果通过动态注册过程去获取设备的DeviceSecret,云端将会拒绝。

598 文档版本:20200417

Page 611: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

因此设备获取到DeviceSecret之后,需要将DeviceSecret固化到非应用存储中,并且即使用户触按

reset按键或者卸载APP或者删除APP数据也不要将DeviceSecret删除掉。 如果设备因为某些原因

导致DeviceSecret被删掉,为了让该设备能够继续被使用,开发者需要将该设备的ProductKey、

DeviceName记录下来,到阿里云控制台删除对应deviceName 的设备,然后重新创建一个相同

deviceName的设备即可。厂家需要注意正式发布的产品不允许出现deviceSecret可以被用户删除的

情况。

1.2.2.12 错误码常见错误码

错误码 子错误码 描述 备注

1101100 - ERROR_SDK_ERROR SDK初始化内部异常

1101101 - ERROR_SDK_INIT_ERROR

- 120 ERROR_PARAMS_DEVICEINFO_INVALID

初始化 三元组信息productKey、deviceName 为空

- 121 ERROR_PARAMS_DEVICE_SECRET_NULL

初始化三元组deviceSecret(设备密钥)为空

- 122 ERROR_PARAMS_SECURE_MODE_ITLS_WITH_PS_NULL

使用itls认证模式,但是三元组 productSecret (产品密钥)为空

-33 - MQTT_CONNECT_ERROR mqtt建联失败

• 检查是否网络正常• 检查三元组是否正确• 域名是否设置正确• 是否多个设备使用同一个三

元组

-4 - ERROR_HTTP HTTP 请求接口错误,如一型一密动态注册失败

• 检测域名是否设置正确• 网络是否有异常• 系统时间是否正常

1101220 - ERROR_COTA_GET_PARAMS_ERROR

获取远程配置请求参数错误

1101230 - ERROR_SHADOW_INVALID_STATE

SDK尚未初始化调用设备影子相关接口

1101231 - ERROR_SHADOW_UPDATE_FAILED

设备影子更新失败,具体错误信息参考error message

文档版本:20200417 599

Page 612: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 子错误码 描述 备注

1101232 - ERROR_SHADOW_PARAMS_INVALID

设备影子更新参数错误

1101312 - ERROR_GATEWAY_PERMIT_JOIN_DEVICE_INFO_INVALID

permitJoin调用的时候初始化的设备信息无效

1101300 - ERROR_GATEWAY_TOPO_NOT_ADDED

尚未添加拓扑关系

1101301 - ERROR_GATEWAY_SUBDEV_NOT_LOGIN

子设备尚未登录

1101302 - ERROR_GATEWAY_SUBDEV_WRAPPER_INFO_NULL

SDK内部子设备信息为空

1101303 - ERROR_GATEWAY_SUBDEV_WRAPPER_NULL

SDK内部子设备不存在

1101304 - ERROR_GATEWAY_SUBDEV_THING_NOT_INITED

子设备物模型未初始化

1101305 - ERROR_GATEWAY_SUBDEV_LABEL_NULL

获取子设备标签为空,一般是子设备未添加后登录

1101306 - ERROR_GATEWAY_SUBDEV_SHADOW_NULL

获取子设备设备影子为空,一般是子设备未添加后登录

1101307 - ERROR_GATEWAY_SUBDEV_COTA_NULL

获取子设备远程配置为空,一般是子设备未添加后登录

1101308 - ERROR_GATEWAY_SUBDEV_INFO_INVALID

子设备三元组信息无效

1101309 - ERROR_GATEWAY_SUBDEV_DISABLED

子设备已被云端禁用

1101310 - ERROR_GATEWAY_SUBDEV_DELETED

子设备已被删除

1101311 - ERROR_GATEWAY_LABEL_PARAMS_INVALID

标签请求参数无效

1101200 - ERROR_TMP_INIT 初始化失败,TMP初始化失败

1101201 - ERROR_DM_GET_TSL_INFO_INVALID

初始化失败,获取TSL信息无效

1101202 - ERROR_DM_INIT_THING_PARAMS_INVALID

初始化失败,物模型获取参数无效

1101203 - ERROR_DM_GET_TMP_IDEVICE

初始化失败,物模型获取失败

600 文档版本:20200417

Page 613: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

错误码 子错误码 描述 备注

1101020 - ERROR_DUPLICATE_SDK_INIT 重复初始化,当前初始化已完成或者正在初始化

100 - ERROR_DUPLICATE_SDK_INIT_DM

设备管理模块重复初始化

101 - ERROR_DUPLICATE_SDK_INIT_LK

LinkKit SDK重复初始化

510 - ERROR_CMP_PARAMS_ERROR CMP 参数错误

514 - ERROR_CMP_REGISTER_CONNECT_ERROR_EXIST

该链接类型已注册,一般可以忽略

517 - ERROR_CMP_SEND_ERROR_CONNECT_NOT_FOUND

发送失败,当前连接类型不存在

521 - ERROR_CMP_SEND_ERROR_CONNECT_NOT_CONNECTED

发送失败,连接未建立

529 - ERROR_CMP_REGISTER_CONNECT_IS_REGISTERING

连接类型正在注册

4201 - ERROR_UNKNOW 客户端内部错误

4101 - ERROR_NETWORK_ERROR 网络错误

4102 - ERROR_SERVER 业务网关错误

4103 - ERROR_BUSINESS 业务错误

1.2.2.13 常见问题RRPC发送应答出错,返回错误码4201

问题描述:当设备端收到RRPC调用后,发送应答出错,错误码4201。

问题原因:客户组装的数据不是一个正确的JSON数据,导致转换时出错。

解决办法:将发送的数据转换成正确的JSON数据后,错误消失

文档版本:20200417 601

Page 614: 阿里云IoT Link Rack 一体机

开发指南 /  1 物联网平台

网关子设备动态注册问题

问题描述:网关代理子设备动态注册失败,动态注册参数是子设备列表,云端返回注册成功,但是返

回的列表为空?

问题原因:

• 子设备未开启动态注册;

• 子设备已经被添加到其他网关设备下了;

问题描述:网关代理子设备动态注册,动态注册列表包含3个子设备,云端返回注册成功信息,但是

只返回了2个子设备信息?

问题原因:

• 该设备未开启动态注册、添加到其他网关设备下

• 子设备信息填写错误

直连设备动态注册问题

问题描述:LinkKit SDK动态注册接口失败,导致初始化失败,无发建联?

问题原因:根据用户日志看到SSLHandshakeException: com.android.org.bouncycastle.jce.

exception.ExtCertPathValidatorException: Could not validate certificate: null,请求还没有到

达云端,mqtt证书检验出了问题,原因是用户的设备时间非正确时间。

602 文档版本:20200417

Page 615: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

2 物联网边缘计算

2.1 边缘端开发指南

2.1.1 设备接入SDK

2.1.1.1 C版本SDK本章为您介绍C版本的SDK使用方法及相关API。Link IoT Edge提供C版本的SDK,名称为linkedge-

thing-access-sdk-c。

C版本开源的SDK源码请参见开源C库。

get_properties_callback

/* * 获取属性(对应设备产品物模型属性定义)的回调函数,需驱动开发者实现获取属性业务逻辑。 * * LinkEdge需要获取某个设备的属性时,SDK会调用该接口间接获取到数据并封装成固定格式后回传给LinkEdge。 * 开发者需要根据设备id和属性名找到设备,将获取到的属性值按照@device_data_t格式填充。 * * @dev_handle: LinkEdge需要获取属性的具体某个设备。 * @properties: 属性值键值结构,驱动开发者需要将根据属性名称获取到的属性值更新到properties中。 * @properties_count: 属性个数。 * @usr_data: 注册设备时,用户传递的私有数据。 * 所有属性均获取成功则返回LE_SUCCESS,其他则返回错误码(参考le_error.h错误码宏定义)。 * */typedef int (*get_properties_callback)(device_handle_t dev_handle, leda_device_data_t properties[], int properties_count, void *usr_data);

set_properties_callback

/* * 设置属性(对应设备产品物模型属性定义)的回调函数,需驱动开发者实现设置属性业务逻辑。 * * LinkEdge需要设置某个设备的属性时,SDK会调用该接口将具体的属性值传递给应用程序,开发者需要在本回调。 * 函数里将属性设置到设备。 * * @dev_handle: LinkEdge需要设置属性的具体某个设备。 * @properties: LinkEdge需要设置的设备的属性名称和值。 * @properties_count: 属性个数。 * @usr_data: 注册设备时,用户传递的私有数据。 *

文档版本:20200417 603

Page 616: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

* 若获取成功则返回LE_SUCCESS,失败则返回错误码(参考le_error.h错误码宏定义)。 * */typedef int (*set_properties_callback)(device_handle_t dev_handle, const leda_device_data_t properties[], int properties_count, void *usr_data);

call_service_callback

/* * 服务(对应设备产品物模型服务定义)调用的回调函数,需要驱动开发者实现服务对应业务逻辑。 * * LinkEdge需要调用某个设备的服务时,SDK会调用该接口将具体的服务参数传递给应用程序,开发者需要在本回调。 * 函数里调用具体的服务,并将服务返回值按照@device_data_t格式填充到output_data。 * * @dev_handle: LinkEdge需要调用服务的具体某个设备。 * @service_name: LinkEdge需要调用的设备的具体某个服务名,名称与设备产品物模型一致。 * @data: LinkEdge需要调用的设备的具体某个服务参数,参数与设备产品物模型保持一致。 * @data_count: LinkEdge需要调用的设备的具体某个服务参数个数。 * @output_data: 开发者需要将服务调用的返回值,按照设备产品物模型规定的服务格式返回到output中。 * @usr_data: 注册设备时,用户传递的私有数据。 * * 若获取成功则返回LE_SUCCESS,失败则返回错误码(参考le_error.h错误码宏定义)。 * */typedef int (*call_service_callback)(device_handle_t dev_handle, const char *service_name, const leda_device_data_t data[], int data_count, leda_device_data_t output_data[], void *usr_data);

leda_report_properties

/* * 上报属性,在设备所属产品物模型中规定了设备的属性上报能力。 * * 上报属性,可以上报一个,也可以多个一起上报。 * * dev_handle: 设备在linkedge本地唯一标识。 * properties: @leda_device_data_t,属性数组。 * properties_count: 本次上报属性个数。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 * */int leda_report_properties(device_handle_t dev_handle, const leda_device_data_t properties[], int properties_count);

leda_report_event

/* * 上报事件,设备具有的事件上报能力在设备产品物模型有规定。 * * * dev_handle: 设备在linkedge本地唯一标识。 * event_name: 事件名称。

604 文档版本:20200417

Page 617: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

* data: @leda_device_data_t,事件参数数组。 * data_count: 事件参数数组长度。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 * */int leda_report_event(device_handle_t dev_handle, const char *event_name, const leda_device_data_t data[], int data_count);

leda_offline

/* * 下线设备,假如设备工作在不正常的状态或设备退出前,可以先下线设备,这样LinkEdge就不会继续下发消息到设备侧。 * * dev_handle: 设备在linkedge本地唯一标识。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 * */int leda_offline(device_handle_t dev_handle);

leda_online

/* * 上线设备,设备只有上线后,才能被LinkEdge识别。 * * dev_handle: 设备在linkedge本地唯一标识。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 */int leda_online(device_handle_t dev_handle);

leda_register_and_online_by_device_name

/* * 通过已在阿里云物联网平台创建的设备device_name,注册并上线设备,申请设备唯一标识符。 * * 若需要注册多个设备,则多次调用该接口即可。 * * product_key: 在阿里云物联网平台创建的产品ProductKey。 * device_name: 在阿里云物联网平台创建的设备名称DeviceName。 * device_cb: 请求调用设备回调函数结构体,详细描述见@leda_device_callback。 * usr_data: 设备注册时传入私有数据,在回调中会传给设备。 * * 阻塞接口,返回值设备在linkedge本地唯一标识,>= 0表示有效,< 0 表示无效。 * */device_handle_t leda_register_and_online_by_device_name(const char *product_key, const char *device_name, leda_device_callback_t *device_cb, void *usr_data);

leda_register_and_online_by_local_name

/* * 通过本地自定义设备名称,注册并上线设备,申请设备唯一标识符。 * * 若需要注册多个设备,则多次调用该接口即可。 * * product_key: 在阿里云物联网平台创建的产品ProductKey。

文档版本:20200417 605

Page 618: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

* local_name: 由设备特征值组成的唯一描述信息,必须保证同一个product_key时,每个设备名称不同。 * device_cb: 请求调用设备回调函数结构体,详细描述见@leda_device_callback。 * usr_data: 设备注册时传入私有数据,在回调中会传给设备。 * * 阻塞接口,返回值设备在linkedge本地唯一标识,>= 0表示有效,< 0 表示无效。 * * 注:在同一产品ProductKey条件设备注册,不允许本接口和leda_register_and_online_by_device_name接口同时使用。 * 即每一个产品ProductKey设备注册必须使用同一接口,否则设备注册会发生不可控行为。 */device_handle_t leda_register_and_online_by_local_name(const char *product_key, const char *local_name, leda_device_callback_t *device_cb, void *usr_data);

leda_init

/* * 驱动模块初始化,模块内部会创建工作线程池,异步执行阿里云物联网平台下发的设备操作请求,工作线程数目通过worker_thread_nums配置。 * * worker_thread_nums: 线程池工作线程数,该数值根据注册设备数量进行设置。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 */int leda_init(int worker_thread_nums);

leda_exit

/* * 驱动模块退出。 * * 模块退出前,释放资源。 * * 阻塞接口。 */void leda_exit(void);

leda_get_driver_info_size

/* * 获取驱动信息长度。 * * 阻塞接口,成功返回驱动信息长度,失败返回0。 */int leda_get_driver_info_size(void);

leda_get_driver_info

/* * 获取驱动信息(在物联网平台配置的驱动配置)。 * * driver_info: 驱动信息,需要提前申请好内存传入。 * size: 驱动信息长度,leda_get_driver_info_size,如果传入driver_info比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 * * 配置格式: { "json":{

606 文档版本:20200417

Page 619: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

"ip":"127.0.0.1", "port":54321 }, "kv":[ { "key":"ip", "value":"127.0.0.1", "note":"ip地址" }, { "key":"port", "value":"54321", "note":"port端口" } ], "fileList":[ { "path":"device_config.json" } ] } */int leda_get_driver_info(char *driver_info, int size);

leda_get_device_info_size

/* * 获取设备信息长度。 * * 阻塞接口,成功返回设备信息长度,失败返回0。 */int leda_get_device_info_size(void);

leda_get_device_info

/* * 获取设备信息(在物联网平台配置的设备配置)。 * * device_info: 设备信息,需要提前申请好内存传入。 * size: 设备信息长度,该长度通过leda_get_device_info_size接口获取,如果传入device_info比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 * * 配置格式: [ { "custom":{ "port":12345, "ip":"127.0.0.1" }, "deviceName":"device1", "productKey":"a1ccxxeypky" } ] */int leda_get_device_info(char *device_info, int size);

leda_get_config_size

/*

文档版本:20200417 607

Page 620: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

* 获取驱动配置长度。 * * 阻塞接口,成功返回驱动配置长度,失败返回0。 */int leda_get_config_size(void);

leda_get_config

/* * 获取驱动所有配置。 * * config: 驱动配置,需要提前申请好内存传入。 * size: 驱动配置长度,该长度通过leda_get_config_size接口获取,如果传入config比实际配置内容长度短,会返回LE_ERROR_INVAILD_PARAM。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 * * 配置格式: { "config":{ "json":{ "ip":"127.0.0.1", "port":54321 }, "kv":[ { "key":"ip", "value":"127.0.0.1", "note":"ip地址" }, { "key":"port", "value":"54321", "note":"port端口" } ], "fileList":[ { "path":"device_config.json" } ] }, "deviceList":[ { "custom":"{"port":12345,"ip":"127.0.0.1"}", "deviceName":"device1", "productKey":"a1ccxxeypky" } ] } */int leda_get_config(char *config, int size);

config_changed_callback

/* * 驱动配置变更回调接口。 * * config: 配置信息。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 */

608 文档版本:20200417

Page 621: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

typedef int (*config_changed_callback)(const char *config);

leda_register_config_changed_callback

/* * 订阅驱动配置变更监听回调。 * * config_cb: 配置变更通知回调接口。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 */int leda_register_config_changed_callback(config_changed_callback config_cb);

leda_get_tsl_size

/* * 获取指定产品ProductKey对应物模型内容长度。 * * product_key: 产品ProductKey。 * * 阻塞接口,成功返回product_key对应物模型内容长度,失败返回0。 */int leda_get_tsl_size(const char *product_key);

leda_get_tsl

/* * 获取指定产品ProductKey对应物模型内容。 * * product_key: 产品ProductKey。 * tsl: 物模型内容,需要提前申请好内存传入。 * size: 物模型内容长度,该长度通过leda_get_tsl_size接口获取,如果传入tsl比实际物模型内容长度短,会返回LE_ERROR_INVAILD_PARAM。 * * 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 */int leda_get_tsl(const char *product_key, char *tsl, int size);

leda_get_tsl_ext_info_size

/* * 获取指定产品ProductKey对应物模型扩展信息内容长度。 * * product_key: 产品ProductKey。 * * 阻塞接口,成功返回product_key对应物模型扩展信息内容长度,失败返回0。 */int leda_get_tsl_ext_info_size(const char *product_key);

leda_get_tsl_ext_info

/* * 获取指定产品ProductKey对应物模型扩展信息内容。 * * product_key: 产品ProductKey。 * tsl_ext_info: 物模型扩展信息,需要提前申请好内存传入。 * size: 物模型扩展信息长度,该长度通过leda_get_tsl_ext_info_size接口获取,如果传入tsl_ext_info比实际物模型扩展信息内容长度短,会返回LE_ERROR_INVAILD_PARAM。 *

文档版本:20200417 609

Page 622: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

* 阻塞接口,成功返回LE_SUCCESS,失败返回错误码。 */int leda_get_tsl_ext_info(const char *product_key, char *tsl_ext_info, int size);

leda_get_device_handle

/* * 获取设备句柄。 * * product_key: 产品ProductKey。 * device_name: 设备名称DeviceName。 * * 阻塞接口,成功返回device_handle_t,失败返回小于0数值。 */device_handle_t leda_get_device_handle(const char *product_key, const char *device_name);

2.1.1.2 Nodejs版本SDK设备接入SDK用于您在网关上开发驱动,将设备连接到网关,进而连接到物联网平台。

Node.js版本开源的SDK源码请见开源的Node.js库。

安装和使用

1. 您可以通过如下命令来安装SDK。

npm install linkedge-thing-access-sdk

2. 安装完成后,您可以根据SDK接口进行驱动开发。

使用SDK开发驱动的示例代码片段如下所示。

const { Config, ThingAccessClient} = require('linkedge-thing-access-sdk');

const callbacks = { setProperties: function (properties) { // Set properties to the physical thing and return the result. // Return an object representing the result or the promise wrapper of the object. return { code: 0, message: 'success', }; }, getProperties: function (keys) { // Get properties from the physical thing and return the result. // Return an object representing the result or the promise wrapper of the object. return { code: 0, message: 'success', params: { key1: 'value1', key2: 'value2', } }; },

610 文档版本:20200417

Page 623: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

callService: function (name, args) { // Call services on the physical thing and return the result. // Return an object representing the result or the promise wrapper of the object. return new Promise((resolve) => { resolve({ code: 0, message: 'success', }); }); }};Config.get() .then(config => { const thingInfos = config.getThingInfos(); thingInfos.forEach(thingInfo => { const client = new ThingAccessClient(thingInfo, callbacks); client.registerAndOnline() .then(() => { return new Promise(() => { setInterval(() => { client.reportEvent('high_temperature', { temperature: 41 }); client.reportProperties({ 'temperature': 41 }); }, 2000); }); }) .catch(err => { console.log(err); client.cleanup(); }); .catch(err => { console.log(err); }); }); });

常量定义

名称 类型 描述

PRODUCT_KEY String 配置对象(传给ThingAccessClient构造函数)的键值,指定云端分配的productKey。

DEVICE_NAME String 配置对象(传给ThingAccessClient构造函数)的键值,指定云端分配的deviceName。

LOCAL_NAME String 配置对象(传给ThingAccessClient构造函数)的键值,指定本地自定义的设备名。

CALL_SERVICE String 回调对象(传给ThingAccessClient构造函数)的键值,指定调用设备服务回调函数。回调函数格式请参见callbacks.callService()。

GET_PROPERTIES String 回调对象(传给ThingAccessClient构造函数)的键值,指定获取设备属性回调函数。回调函数格式请参见callbacks.getProperties()。

文档版本:20200417 611

Page 624: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

名称 类型 描述

SET_PROPERTIES String 回调对象(传给ThingAccessClient构造函数)的键值,指定设置设备属性回调函数。回调函数格式请参见callbacks.setProperties()。

RESULT_SUCCESS Number 操作成功。用于回调函数返回状态码。

RESULT_FAILURE Number 操作失败。用于回调函数返回状态码。

ERROR_CLEANUP String 调用cleanup()出错错误码。

ERROR_CONNECT String 调用registerAndOnline()出错错误码。

ERROR_DISCONNECT String 调用offline()出错错误码。

ERROR_GET_CONFIG String 调用getConfig()出错错误码。

ERROR_GET_TSL String 调用getTsl()出错错误码。

ERROR_GET_TSL_EXT_INFO

String 调用getTslExtInfo()出错错误码。

ERROR_UNREGISTER String 调用unregister()出错错误码。

Config

驱动相关配置信息。

• static get()

返回全局的驱动配置对象,该配置通常在设备与驱动程序关联时由系统自动生成。该接口

与getConfig()的区别在于前者返回配置对象,后者返回配置字符串。

说明:

该接口的Config.get()调用方法与getConfig()接口的区别在于,getConfig()返回配置字符

串,Config.get()返回配置对象。

返回值:

Promise<Config>

• static registerChangedCallback(callback)

注册配置变更回调函数。

表 2-1: 请求参数

名称 类型 描述

callback(String) Function 回调函数,配置变更时被调用。

612 文档版本:20200417

Page 625: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

• static unregisterChangedCallback(callback)

注销配置变更回调函数。

表 2-2: 请求参数

名称 类型 描述

callback(String) Function 回调函数,配置变更时被调用。

• Config(string)

基于配置字符串构造新的Config对象。

表 2-3: 请求参数

名称 类型 描述

string String JSON配置字符串。

• getThingInfos()

返回所有设备相关信息。

返回值:

ThingInfo[]

• getDriverInfo()

返回驱动相关信息。

返回值:

Object

ThingInfo

ThingInfo(productKey, deviceName, custom)

构造一个新的ThingInfo对象。

表 2-4: 请求参数

名称 类型 描述

productKey String 产品唯一标识。

deviceName String 设备名称。

custom Object 设备自定义配置。

文档版本:20200417 613

Page 626: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

ThingAccessClient

设备接入客户端,您可以通过该客户端来主动上报设备属性或事件,也可被动接受云端下发的指令。

• ThingAccessClient(config, callbacks)

构造函数,使用指定的config和callbacks构造。

表 2-5: 请求参数

名称 类型 描述

config Object 元数据,用于配置该客户端。取值格式为:

{ "productKey": "Your Product Key", "deviceName": "Your Device Name"}

callbacks Object 回调函数对象。取值格式为:

callbacks: { setProperties: function(properties) {}, getProperties: function(keys) {}, callService: function(name, args) {}}

- 指定设置设备属性的回调参数,请参见本文下方callbacks.setProperties内容

- 指定获取设备属性的回调参数,请参见本文下方callbacks.getProperties内容

- 指定调用设备服务的回调参数,请参见本文下方callbacks.callService内容

• callbacks.setProperties(properties)

设置具体设备属性的回调函数。通过回调函数,实现设置设备的属性。

表 2-6: 请求参数

名称 类型 描述

properties Object 设置属性的对象,取值格式为:

{ "key1": "value1", "key2": "value2"}

返回值:

{614 文档版本:20200417

Page 627: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

"code": 0, "message": "string", "params": {}}

表 2-7: 返回参数

名称 类型 描述

code Number 状态码。

- 0:接口调用成功。- 非0:接口调用失败,报非0值对应的错误。

message String 可选参数,状态描述信息。

params Object 可选参数,用于返回每个属性的设置结果,其值为每个属性设置后的实际值。

• callbacks.getProperties(keys)

获取具体设备属性的回调函数。通过回调函数,实现获取设备的属性。

表 2-8: 请求参数

名称 类型 描述

keys String[] 获取属性对应的名称,取值格式为:

['key1', 'key2']

返回值:

{ "code": 0, "message": "string", "params": {}}

表 2-9: 返回参数

名称 类型 描述

code Number 状态码。

- 0:接口调用成功。- 非0:接口调用失败,报非0值对应的错误。

message String 可选参数,状态描述信息。

params Object 可选参数,用于获取属性成功时,返回对应的属性值。

文档版本:20200417 615

Page 628: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

• callbacks.callService(name, args)

调用设备服务回调函数。通过回调函数,实现调动设备服务。

表 2-10: 请求参数

名称 类型 描述

name String 设备服务名称。

args Object 服务入参列表,取值格式为:

{ "key1": "value1", "key2": "value2"}

表 2-11: 返回参数

名称 类型 描述

code Number 状态码。

- 0:接口调用成功。- 非0:接口调用失败,报非0值对应的错误。

message String 可选参数,状态描述信息。

params Object 可选参数,用于调用设备服务成功时,返回额外的信息。

• setup()

设备接入客户端初始化。

注意:

616 文档版本:20200417

Page 629: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

Link IoT Edge当前版本已不再使用该接口,之前遗留的调用不受影响。

返回值:

Promise<Void>

• registerAndOnline()

将设备注册到网关中并通知网关上线设备。设备需要注册并上线后,设备端才能收到云端下发的

指令或者发送数据到云端。

返回值:

Promise<Void>

• online()

通知网关设备已上线,该接口一般在设备离线后再次上线时使用。

返回值:

Promise<Void>

• offline()

通知网关设备已离线。

返回值:

Promise<Void>

• reportEvent(eventName, args)

主动上报设备事件。

表 2-12: 请求参数

名称 类型 描述

eventName String 事件对应的名称,与您在产品定义中创建事件的名称一致。

文档版本:20200417 617

Page 630: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

名称 类型 描述

args Object 事件中包含的属性key与value,取值格式为:

{ "key1": "value1", "key2": "value2"}

• reportProperties(properties)

主动上报设备属性。

表 2-13: 请求参数

名称 类型 描述

properties Object 属性中包含的属性key与value,取值格式为:

{ "key1": "value1", "key2": "value2"}

• getTsl()

返回TSL字符串,数据格式与云端一致。

返回值:

Promise<Void>

• getTslConfig()

注意:

618 文档版本:20200417

Page 631: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

Link IoT Edge当前版本已不再使用该接口,已使用getTslExtInfo()接口代替,之前遗留的调用

不受影响。

返回TSL配置字符串。

返回值:

Promise<String>

• getTslExtInfo()

返回TSL扩展信息字符串。

返回值:

Promise<String>

• cleanup()

资源回收接口,您可以使用该接口回收您的资源。

返回值:

Promise<Void>

• unregister()

从网关中移除设备。请谨慎使用该接口。

返回值:

Promise<Void>

getConfig()

获取驱动配置字符串,该配置通常在设备与驱动程序关联时由系统自动生成。

说明:

该接口与static get()接口Config.get()调用方法的区别在于getConfig()返回配置字符

串,Config.get()返回配置对象。

返回值:

Promise<String>

destroy()

销毁库内部所有资源。通常不再使用此库时调用destroy()接口。

文档版本:20200417 619

Page 632: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

返回值:

Promise<Void>

2.1.1.3 Python版本SDKLink IoT Edge提供Python版本的SDK,名称为lethingaccesssdk。本章为您介绍Python版本

的SDK使用方法及相关SDK。

Python版本开源的SDK源码请见开源的Python库。

安装和使用

1. 您可以通过如下命令来安装SDK。

pip3 install lethingaccesssdk

2. 安装完成后,您可以根据SDK接口进行驱动开发。

使用SDK开发驱动的示例代码片段如下所示。

# -*- coding: utf-8 -*-import loggingimport timeimport lethingaccesssdkfrom threading import Timer# Base on device, User need to implement the getProperties, setProperties and callService function.class Temperature_device(lethingaccesssdk.ThingCallback): def __init__(self): self.temperature = 41 self.humidity = 80 def getProperties(self, input_value): ''' Get properties from the physical thing and return the result. :param input_value: :return: ''' retDict = { "temperature": 41, "humidity": 80 } return 0, retDict def setProperties(self, input_value): ''' Set properties to the physical thing and return the result. :param input_value: :return: ''' return 0, {} def callService(self, name, input_value): ''' Call services on the physical thing and return the result. :param name: :param input_value: :return: ''' return 0, {}def thing_behavior(client, device):

620 文档版本:20200417

Page 633: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

while True: properties = {"temperature": device.temperature, "humidity": device.humidity} client.reportProperties(properties) client.reportEvent("high_temperature", {"temperature": 41}) time.sleep(2)try: thing_config = lethingaccesssdk.Config().getThingInfos() for config in thing_config: device = Temperature_device() client = lethingaccesssdk.ThingAccessClient(config) client.registerAndonline(device) t = Timer(2, thing_behavior, (client, device)) t.start()except Exception as e: logging.error(e)# don't remove this functiondef handler(event, context): return 'hello world'

Config

驱动相关配置信息。

• Config()

基于当前驱动配置字符串构造新的Config对象。

• getThingInfos()

返回所有设备相关信息。

返回值说明如下:

返回设备用于连接Link IoT Edge的配置信息的封装。

表 2-14: 返回参数

名称 类型 描述

ThingInfo List 设备信息。

表 2-15: ThingInfo参数说明

名称 类型 描述

productKey String 产品唯一标识。

deviceName String 设备名称。

custom Object 设备自定义配置。

文档版本:20200417 621

Page 634: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

• getDriverInfo()

返回驱动相关信息。

返回值:

dict

ThingCallback

首先根据真实设备,命名一个类(如Demo_device)继承ThingCallback,然后在该

类(Demo_device)中实现setProperties、getProperties和callService三个函数。

• setProperties

设置具体设备属性函数。

表 2-16: 请求参数

名称 类型 描述

properties Dict 设置属性,取值格式为:

{ "property1": "value1", "property2": "value2"}

表 2-17: 返回参数

名称 类型 描述

code Integer 若获取成功则返回0,失败则返回非0错误码。

output Dict 数据内容自定义,例如:

{ "key1": xxx, "key2": yyy, ...}

若无返回数据,则值为空{}。

622 文档版本:20200417

Page 635: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

• getProperties

获取具体设备属性的函数。

表 2-18: 请求参数

名称 类型 描述

keys List 获取属性对应的名称,取值格式为:

['key1', 'key2']

表 2-19: 返回参数

名称 类型 描述

code Integer 若获取成功则返回0,失败则返回非0错误码。

output Dict 返回值,例如:

{ 'property1': xxx, 'property2': yyy, ..}.}

• callService

调用设备服务函数。

表 2-20: 请求参数

名称 类型 描述

name String 设备服务名称。

args Dict 服务入参列表,取值格式为:

{ "key1": "value1", "key2": "value2"}

表 2-21: 返回参数

名称 类型 描述

code Integer 若获取成功则返回0,失败则返回非0错误码。

文档版本:20200417 623

Page 636: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

名称 类型 描述

output Dict 数据内容自定义,例如:

{ "key1": xxx, "key2": yyy, ...}

若无返回数据,则值为空{}。

ThingAccessClient(config)

设备接入客户端,您可以通过该客户端来主动上报设备属性或事件,也可被动接受云端下发的指令。

表 2-22: 请求参数

名称 类型 描述

config Dict 包括云端分配的ProductKey和deviceName。

例如,

{ "productKey": "xxx", "deviceName": "yyy"}

• registerAndOnline(ThingCallback)

将设备注册到网关中并通知网关上线设备。设备需要注册并上线后,设备端才能收到云端下发的

指令或者发送数据到云端。

表 2-23: 请求参数

名称 类型 描述

ThingCallback Object 设备的callback对象。

624 文档版本:20200417

Page 637: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

• reportProperties(properties)

主动上报设备属性。

表 2-24: 请求参数

名称 类型 描述

properties Dict 属性中包含的属性key与value,取值格式为:

{ "key1": "value1", "key2": "value2"}

• reportEvent(eventName, args)

主动上报设备事件。

表 2-25: 请求参数

名称 类型 描述

eventName String 事件对应的名称,与您在产品定义中创建事件的名称一致。

args Dict 事件中包含的属性key与value,取值格式为:

{ "key1": "value1", "key2": "value2"}

• getTsl()

返回TSL字符串,数据格式与云端一致。

返回值:

TSL字符串

• getTslExtInfo()

返回TSL扩展信息字符串。

返回值:

TSL扩展信息字符串

• online()

通知网关设备上线,该接口一般在设备离线后再次上线时使用。

文档版本:20200417 625

Page 638: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

• offline()

通知网关设备已离线。

• cleanup()

资源回收接口,您可以使用该接口回收您的资源。

• unregister()

移除设备和网关的绑定关系。请谨慎使用该接口。

getConfig()

获取驱动相关配置信息。

返回值为驱动配置信息字符串。

2.1.2 函数计算SDK

2.1.2.1 简介边缘函数计算SDK主要包含了设备操作、消息发布、函数调用相关功能的接口。

功能概述

以下介绍函数计算SDK的具体功能。

• 设备操作

设备操作是IoT场景中最常见的需求,为了方便对设备信息进行读写,边缘函数计算SDK提供了如

下四个功能API:

- 获取设备属性

- 设置设备属性

- 调用设备服务

- 根据标签获取设备列表

• 消息发布

边缘端的消息发布接口,提供向指定Topic发送消息的能力。您还可以结合设置,可将消息流转到

订阅了该Topic消息的其它函数和将消息发送到云端。

• 函数调用

函数计算是基于事件驱动的编程模型。事件源可以是设备消息和定时器,也可以是其它函数的调

用请求。每一个函数计算不仅以一个独立的程序任务存在,还可以跟普通函数一样被调用,接收

调用时传入的参数,并返回处理结果。

626 文档版本:20200417

Page 639: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

安装SDK

边缘函数计算SDK提供Node.js版本和Python版本,并已经集成在Link IoT Edge软件包内,可直接

引用。

1. 获取SDK库。

• Node.js SDK 源码,请参见边缘计算SDK开源Node.js库。

• Python SDK 源码,请参见边缘计算SDK开源Python库。

2. 引用SDK库。

• 引用Node.js SDK库。

const leSdk = require('linkedge-core-sdk');

• 引用Python SDK库。

import lecoresdk

2.1.2.2 Nodejs

2.1.2.2.1 Publish调用该接口发布消息到自定义的Topic。

publish(params,callback)

参数 类型 描述

params object 参数对象。需包含的必需参数,请参见下方params参数说明表。

callback(err) function 回调函数。遵循JavaScript标准实践。

• 调用成功,err为null。• 调用失败,err包含发生的错误信息。

表 2-26: params参数说明

参数 类型 描述

topic String 接收消息的目标Topic。

payload String 消息负载。

调用示例

以下示例中定义为每当有外部事件触发时,向/hello/world这个Topic 发送一条消息。

'use strict';

文档版本:20200417 627

Page 640: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

const leSdk = require('linkedge-core-sdk');const iotData = new leSdk.IoTData();

exports.handler = function (event, context, callback) { var message = { topic: '/hello/world', payload: 'Hello World.', }; iotData.publish(message, (err, data)=> { if (err == null) { console.log("-- Publish HelloWorld success."); } callback(err); });};

2.1.2.2.2 getThingProperties调用该接口获取指定设备的某项属性值。

getThingProperties(params, callback)

参数 类型 描述

params object 参数对象。需包含的必需参数,请参见下方params参数说明表。

callback(err, data)

function 回调函数。遵循JavaScript标准实践。具体请参见下方callback参数说明表。

表 2-27: params 参数说明

参数 类型 描述

productKey String 设备所属产品的ProductKey,创建产品时,物联网平台为该产品生成的唯一标识。

deviceName String 设备的DeviceName,创建设备时生成的名称。

payload Array 包含要获取的设备属性的identifier数组。调用成功将返回

该属性当前的对应值。

在物联网平台控制台,设备所属产品详情页的功能定

义页,单击查看物模型,即可查看各属性的identifier。

表 2-28: callback参数说明

参数 类型 描述

err Error • 调用成功,err为null。• 调用失败,err包含发生的错误信息。

628 文档版本:20200417

Page 641: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

参数 类型 描述

data object 返回指定设备属性的值。

调用示例

以下示例获取设备LightDev2的LightSwitch属性值(即开关状态)。

'use strict';

const leSdk = require('linkedge-core-sdk');const iotData = new leSdk.IoTData();

const getPropertiesParams = { productKey: 'a1ZJTVsqj2y', // Please replace it with your Product Key. deviceName: 'LightDev2', // Please replace it with your Device Name. payload: ['LightSwitch'] // The property defined in the Product TSL.};/* Promise wrapper for getThingProperties. */ function getThingProperties(params) { return new Promise((resolve, reject) => { iotData.getThingProperties(params, (err, data) => { err ? reject(err) : resolve(data); }); });}

exports.handler = function (event, context, callback) { getThingProperties(getPropertiesParams).then((data) => { console.log(data); // Return value example: { LightSwitch: 0 } if (null == data.LightSwitch) { console.log("-- [Warn] No property LightSwitch return."); } else { console.log("-- [Success] LightSwitch = " + data.LightSwitch); if (data.LightSwitch == '0') { console.log("-- Light is off."); } else { console.log("-- Light is on."); } } callback(null); }).catch((err) => { console.log(err); callback(err); });};

2.1.2.2.3 setThingProperties调用该接口为指定设备设置某项属性值。

setThingProperties(params, callback)

参数 类型 描述

params object 参数对象。需包含的必需参数,请参见下方params参数说明表。

文档版本:20200417 629

Page 642: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

参数 类型 描述

callback(err) function 回调函数。遵循JavaScript标准实践。

• 调用成功,err为null。• 调用失败,err包含发生的错误信息。

表 2-29: params参数说明

参数 类型 描述

productKey String 设备所属产品的ProductKey,创建产品时,物联网平台为该产品生成的唯一标识。

deviceName String 设备的DeviceName,创建设备时生成的名称。

payload Object 包含属性identifier和要设置的属性值。

在物联网平台控制台,设备所属产品详情页的功能定

义页,单击查看物模型,即可查看各属性的identifier和取

值范围。

调用示例

以下示例设置设备LightDev2的LightSwitch属性值为1(即“开”状态)。

'use strict';

const leSdk = require('linkedge-core-sdk');const iotData = new leSdk.IoTData();

const setPropertiesParams = { productKey: 'a1ZJTVsqj2y', // Please replace it with your Product Key. deviceName: 'LightDev2', // Please replace it with your Device Name. payload: {'LightSwitch': '1'} // The property defined in the Product TSL.};/* Promise wrapper for setThingProperties. */ function setThingProperties(params) { return new Promise((resolve, reject) => { iotData.setThingProperties(params, (err, data) => { err ? reject(err) : resolve(data); }); });}

exports.handler = function (event, context, callback) { setThingProperties(setPropertiesParams).then((data) => { console.log("-- Set Property Success. Return " + JSON.stringify(data)); callback(null); }).catch((err) => { console.log(err); callback(err); });

630 文档版本:20200417

Page 643: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

};

2.1.2.2.4 callThingService调用该接口调用指定设备的某项服务。

callThingService(params, callback)

参数 类型 描述

params object 参数对象。需包含的必需参数,请参见下方params参数说明表。

callback(err, data)

function 回调函数。遵循JavaScript标准实践。具体请参见下方callback参数说明表。

表 2-30: params参数说明

参数 类型 描述

productKey String 设备所属产品的ProductKey,创建产品时,物联网平台为该产品生成的唯一标识。

deviceName String 设备的DeviceName,创建设备时生成的名称。

service String 被调用的服务identifier。

在物联网平台控制台,设备所属产品详情页的功能定

义页,单击查看物模型,即可查看各服务的identifier。

payload String|Buffer 包含指定服务的输入参数的identifier和值。

可以通过查看物模型,查看服务的输入参数identifier和取

值范围。

表 2-31: callback参数说明

参数 类型 描述

err Error • 调用成功,err为null。• 调用失败,err包含发生的错误信息。

data object 被调用服务的返回值。

调用示例

以下示例调用设备LightDev2的服务turn。

'use strict';

文档版本:20200417 631

Page 644: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

const leSdk = require('linkedge-core-sdk');const iotData = new leSdk.IoTData();

const callServiceParams = { productKey: 'a1ZJTVsqj2y', // Please replace it with your Product Key. deviceName: 'LightDev2', // Please replace it with your Device Name. service: 'turn', // The service defined in the Product TSL. payload: {'LightSwitch': 0},};/* Promise wrapper for callThingService. */function callThingService(params) { return new Promise((resolve, reject) => { iotData.callThingService(params, (err, data) => { err ? reject(err) : resolve(data); }); });}

exports.handler = function (event, context, callback) { callThingService(callServiceParams).then((data) => { console.log("-- Call service Success. Return " + JSON.stringify(data)); callback(null); }).catch((err) => { console.log(err); callback(err); });};

2.1.2.2.5 getThingsWithTags调用该接口根据标签获取设备列表。

说明

若传入多个标签,仅返回满足所有标签条件的设备列表。

getThingsWithTags(params, callback)

参数 类型 描述

params object 参数对象。需包含的必需参数,请参见下方params参数说明表。

callback(err, data)

function 回调函数。遵循JavaScript标准实践。具体请参见下方callback参数说明表。

表 2-32: params参数说明

参数 类型 描述

payload Array 包含标签信息。一个由{<标签名>:<标签值>}组成的数组。

632 文档版本:20200417

Page 645: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

表 2-33: callback参数说明

参数 类型 描述

err Error • 调用成功,err为null。• 调用失败,err包含发生的错误信息。

data Array 返回满足标签条件的设备信息数组。

调用示例

以下示例查询标签为 location: master bedroom 的设备。

'use strict';

const leSdk = require('linkedge-core-sdk');const iotData = new leSdk.IoTData();

const deviceTags = { payload: [{'location': 'master bedroom'}],};/* Promise wrapper for getThingsWithTags. */function getThingsWithTags(params) { return new Promise((resolve, reject) => { iotData.getThingsWithTags(params, (err, things) => { err ? reject(err) : resolve(things); }); });}

exports.handler = function (event, context, callback) { getThingsWithTags(deviceTags).then((things) => { console.log(JSON.stringify(things)); for(var i=0; i<things.length; i++) {  console.log('-- productKey='+things[i]["productKey"] + ', deviceName='+things[i]["deviceName"]); } callback(null); }).catch((err) => { console.log(err); callback(err); });};

2.1.2.2.6 invokeFunction调用该接口,调用指定的函数。

说明

调用函数和发布消息,两者都可以在进程(函数)间传递消息,但区别是

• 函数调用消息是双向的。调用者发送消息给被调用者后,会收到被调用者处理后返回的消息;

• 发布消息是单向的。发送者不需要被调用者的返回信息。

文档版本:20200417 633

Page 646: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

invokeFunction(params, callback)

参数 类型 描述

params object 参数对象。需包含的必需参数,请参见下方params参数说明表。

callback(err, data)

function 回调函数。遵循JavaScript标准实践。具体请参见下方callback参数说明表。

表 2-34: params 参数说明

参数 类型 描述

serviceName String 服务名。函数在阿里云函数计算中所属服务的名称。

functionName String 函数名,在阿里云函数计算中设置的函数名。

invocationType String 调用类型。

• Sync:同步调用。• Async:异步调用。

默认为同步调用。

payload String|Buffer 参数信息作为函数的输入。

表 2-35: callback参数说明

参数 类型 描述

err Error • 调用成功,err为null。• 调用失败,err包含发生的错误信息。

data object 被调函数的返回值。

调用示例

• 调用者函数代码示例

在Invoker中,调用serviceName=EdgeFC, functionName=helloworld的函数。

'use strict';

const leSdk = require('linkedge-core-sdk');const fc = new leSdk.FCClient();

module.exports.handler = function (event, context, callback) { var ctx = { custom: { data: 'Custom context from Invoker', }, }; var invokerContext = Buffer.from(JSON.stringify(ctx)).toString('base64');

634 文档版本:20200417

Page 647: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

var invokeParams = { serviceName: 'EdgeFC', functionName: 'helloworld', invocationType: 'Sync', invokerContext: invokerContext, payload: 'String message from Invoker.', }; fc.invokeFunction(invokeParams, (err, data) => { if (err) { console.log(err); } else { console.log(data.payload); // Message from helloworld } callback(null); });};

• 被调用函数代码示例

以下helloworld函数代码表示被调用函数如何解析调用者传入的参数,以及如何返回结果给调用

者。

module.exports.handler = function(event, context, callback) { console.log(event); // String message from Invoker. console.log(context); // { requestId: '4', invokerContext: {custom: { data: 'Custom data from Invoker' }}} console.log(context.invokerContext.custom.data); // Custom data from Invoker console.log('-- hello world'); callback(null, 'Message from helloworld'); // Return the result to Invoker.};

2.1.2.3 Python

2.1.2.3.1 publish调用该接口发布消息到自定义的Topic。

publish(params)

表 2-36: 请求参数

参数 类型 描述

params dict 参数对象。需包含的必需参数,请参见下方params参数说明表。

表 2-37: params参数说明

参数 类型 描述

topic String 接收消息的目标Topic。

payload String 消息负载。

文档版本:20200417 635

Page 648: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

表 2-38: 返回值

参数 类型 描述

return dict 调用成功,则返回成功信息;否则返回出错信息。

说明:返回的成功信息仅表示接口调用成功,不代表消息发送成功。

调用示例

以下示例中定义每当有外部事件触发时,向/topic/hello这个Topic 发送一条消息。

# -*- coding: utf-8 -*-import lecoresdk

lesdk = lecoresdk.IoTData()

def handler(event, context): pub_params = {"topic": "/topic/hello", "payload": "Hello World"} lesdk.publish(pub_params) print("Publish message to /topic/hello.") return 'Hello world'

2.1.2.3.2 getThingProperties调用该接口获取指定设备的某项属性值。

getThingProperties(params)

表 2-39: 请求参数

参数 类型 描述

params dict 请求参数对象。需包含的必需参数,请参见下方params参数说明表。

表 2-40: params 参数说明

参数 类型 描述

productKey String 设备所属产品的ProductKey,创建产品时,物联网平台为该产品生成的唯一标识。

deviceName String 设备的DeviceName,创建设备时生成的名称。

636 文档版本:20200417

Page 649: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

参数 类型 描述

payload List 包含要获取的设备属性的identifier数组。调用成功将返回

该属性当前的对应值。

在物联网平台控制台,设备所属产品详情页的功能定

义页,单击查看物模型,即可查看各属性的identifier。

表 2-41: 返回值

参数 类型 描述

return dict 调用成功,则返回要获取的设备属性的值;否则返回驱动上报的出错信息。

调用示例

以下示例获取设备LightDev2的LightSwitch属性值(即开关状态)。

# -*- coding: utf-8 -*-import lecoresdk

lesdk = lecoresdk.IoTData()

def handler(event, context): get_params = {"productKey": "a1ZJTVsqj2y", # Please replace it with your Product Key. "deviceName": "LightDev2", # Please replace it with your Device Name. "payload": ["LightSwitch"]} # The property defined in the Product TSL. res = lesdk.getThingProperties(get_params) print(res) if 'LightSwitch' in res.keys(): print("-- [Success] LightSwitch = %s" % res['LightSwitch']) if res['LightSwitch'] == '0': print("-- Light is off.") else: print("-- Light is on.") else: print("-- [Warn] No property LightSwitch return."); return 'OK'

2.1.2.3.3 setThingProperties调用该接口为指定设备设置某项属性值。

setThingProperties(params)

表 2-42: 请求参数

参数 类型 描述

params dict 请求参数对象。需包含的必需参数,请参见下方params参数说明表。

文档版本:20200417 637

Page 650: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

表 2-43: params 参数说明

参数 类型 描述

productKey String 设备所属产品的ProductKey,创建产品时,物联网平台为该产品生成的唯一标识。

deviceName String 设备的DeviceName,创建设备时生成的名称。

payload dict 包含属性identifier和要设置的属性值。

在物联网平台控制台,设备所属产品详情页的功能定

义页,单击查看物模型,即可查看各属性的identifier和取

值范围。

表 2-44: 返回值

参数 类型 描述

return dict 调用成功,则返回true;否则返回驱动上报的出错信息。

调用示例

以下示例设置设备LightDev的LightSwitch属性值为0(即“关”状态)。

# -*- coding: utf-8 -*-import lecoresdk

lesdk = lecoresdk.IoTData()

def handler(event, context): set_params = {"productKey": "a1ZJTVsqj2y", # Please replace it with your Product Key. "deviceName": "LightDev", # Please replace it with your Device Name. "payload": {"LightSwitch":0}}# The property defined in the Product TSL. res = lesdk.setThingProperties(set_params) print(res) return 'OK'

2.1.2.3.4 callThingService调用该接口调用指定设备的某项服务。

callThingService(params)

表 2-45: 请求参数

参数 类型 描述

params dict 请求参数对象。需包含的必需参数,请参见本文下方params参数说明表。

638 文档版本:20200417

Page 651: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

表 2-46: params参数说明

参数 类型 描述

productKey String 设备所属产品的ProductKey,创建产品时,物联网平台为该产品生成的唯一标识。

deviceName String 设备的DeviceName,创建设备时生成的名称。

service String 被调用的服务identifier。

在物联网平台控制台,设备所属产品详情页的功能定

义页,单击查看物模型,即可查看各服务的identifier。

payload String|Bytes 包含指定服务的输入参数的identifier和值。

可以通过查看物模型,查看服务的输入参数identifier和取

值范围。

表 2-47: 返回值

参数 类型 描述

return dict 调用成功,则返回被调用服务的返回值;否则返回驱动上报的出错信息。

调用示例

以下示例调用设备LightDev2的turn服务。

# -*- coding: utf-8 -*-import lecoresdk

lesdk = lecoresdk.IoTData()

def handler(event, context): get_params = {"productKey": "a1ZJTVsqj2y", # Please replace it with your Product Key. "deviceName": "LightDev2", # Please replace it with your Device Name. "service":"turn", # The service defined in the Product TSL. "payload": {"LightSwitch": 1}} res = lesdk.callThingService(get_params) print(res) return 'OK'

2.1.2.3.5 getThingsWithTags调用该接口根据标签获取设备列表。

限制说明

若传入多个标签,仅返回满足所有标签条件的设备列表。

文档版本:20200417 639

Page 652: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

getThingsWithTags(params)

表 2-48: 请求参数

参数 类型 描述

params dict 参数对象。需包含的必需参数,请参见下方params参数说明表。

表 2-49: params参数说明

参数 类型 描述

payload List 标签信息数组。标签是由{"key":"value"}组成的数组。

表 2-50: 返回值

参数 类型 描述

return dict 调用成功,则返回满足条件的设备信息数组;否则返回驱动上报的出错信息。

调用示例

以下示例查询标签为 location: master bedroom 的设备。

# -*- coding: utf-8 -*-import lecoresdk

lesdk = lecoresdk.IoTData()

def handler(event, context): get_params = {"payload": [{"location":"master bedroom"}]} res = lesdk.getThingsWithTags(get_params) print(res) for device in res: print("device_%s: PK=%s DN=%s" % (res.index(device) + 1, device['productKey'], device['deviceName'])) return 'OK'

2.1.2.3.6 invokeFunction调用该接口,调用指定的函数。

说明

调用函数和发布消息,两者都可以在进程(函数)间传递消息,但区别是

• 函数调用消息是双向的。调用者发送消息给被调用者后,会收到被调用者处理后返回的消息;

• 发布消息是单向的。发送者不需要被调用者的返回信息。

640 文档版本:20200417

Page 653: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

invokeFunction(params)

表 2-51: 请求参数

参数 类型 描述

params dict 参数对象。需包含的必需参数,请参见下方params参数说明表。

表 2-52: params 参数说明

参数 类型 描述

serviceName String 服务名。函数在阿里云函数计算中所属服务的名称。

functionName String 函数名,在阿里云函数计算中设置的函数名。

invocationType String 调用类型。

• Sync:同步调用。• Async:异步调用。

默认为同步调用。

payload String|Bytes 参数信息作为函数的输入。

表 2-53: 返回值

参数 类型 描述

return dict 被调用函数的返回值。

调用示例

• 调用者函数代码示例

在Invoker中,调用serviceName=EdgeFC,functionName=helloworld的函数。

# -*- coding: utf-8 -*-import lecoresdkedgefc = lecoresdk.Client()

def handler(event, context): context = {"custom": {"data": "customData"}} invokeParams = { "serviceName": 'EdgeFC', "functionName": 'helloworld', "invocationType": 'Sync', "invokerContext": context, "payload": 'String message from Python Invoker.' }; res = edgefc.invoke_function(invokeParams) print(res)

文档版本:20200417 641

Page 654: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

return 'OK'

• 被调用函数代码示例

以下helloworld函数代码表示被调用函数如何解析调用者传入的参数,以及如何返回结果给调用

者。

# -*- coding: utf-8 -*-import loggingimport lecoresdk

def handler(event, context): logging.debug(event) logging.debug(context) return 'hello world'

2.1.3 边缘端HTTP API

2.1.3.1 概述物联网边缘计算支持使用边缘端API管理接入到网关的设备,包括获取设备及设备列表、设置设备属

性、订阅设备事件等。

边缘端API的对外提供服务的端口号为9999,所有接口均支持HTTPS单向认证。

权限校验机制

边缘端API目前支持Cookie认证方式,开发者必须通过CreateAuthCookie接口获取认证Cookie才能

进一步调用其它API。CreateAuthCookie接口采用Basic Authentication认证方式,开发者必须知

道网关的用户名与密码,并且该用户名具备访问相应API的权限才能完成接口调用。

说明:

网关的初始用户名为admin,密码为admin1234,可通过访问边缘网关控制台修改用户名密码

和API访问权限。访问边缘网关控制台的操作请参考远程服务访问。

API列表

• 身份认证类

API名称 API描述

CreateAuthCookie 创建认证Cookie。

DeleteAuthCookie 删除认证Cookie。

• 设备管理类

API 名称 API 描述

SetThingProperties 设置设备属性。

642 文档版本:20200417

Page 655: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

API 名称 API 描述

GetThingProperties 获取设备属性。

CallThingServices 调用设备服务。

BulkActions 对设备进行批量操作。

2.1.3.2 状态码边缘端API的状态码如下表格所示。

返回码(code) 返回信息 描述

200 Success 接口调用成功。

201 Created 请求成功并且服务器创建了新的资源。

302 Move temporarily URL重定向。

400 Bad Request 报该错误码可能有如下两种原因:

• 语义有误,当前请求无法被服务器理解,除非进行修改,否则客户端不会重复提交该请求。

• 请求参数有误。

401 Unauthorized 当前请求需要用户验证。即Cookie已过期,需要重新调用CreateAuthCookie接口更新Cookie,否则将无法继续调用其他API。

403 Forbidden 服务器已经理解请求,但拒绝执行请求。需要进行权限校验,确认当前登录用户是否有权限调用请求API。

404 Not Found 请求失败,未在服务器上发现请求所希望得到的资源。需要确认请求的API参数是否正确。

405 Method Not Allowed 请求行中指定的请求方法不能被用于请求相应的资源。例如,不支持使用POST方法。

421 Too Many Connections

从当前客户端所在的IP地址连接到服务器的连接数超过了服务器允许的最大限制。

说明:此处的IP地址指的是从服务器上看到的客户端地址,例如用户的网关或者代理服务器地址。

500 Internal Server Error 服务器遇到了一个未曾预料的状况,导致无法完成对请求的处理。通常情况下,服务器的源代码出现错误时报该错误码。

文档版本:20200417 643

Page 656: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

返回码(code) 返回信息 描述

503 Service Unavailable 由于临时的服务器维护或服务器过载,因此服务

器当前无法处理请求。

2.1.3.3 身份认证

2.1.3.3.1 CreateAuthCookie使用该接口创建一个新的认证Cookie。

请求语法

POST /2019-09-30/auth/cookiesAuthorization: Authorization

请求参数

参数名称 类型 是否必选 描述

Authorization String 是 支持Basic认证。格式为 Basic base64(username:password)。

例如Basic Y2h5aW5n********NTY=。

返回语法

HTTP/1.1 StatusCodeSet-Cookie: CookieContent-Type: application/json

Payload

返回参数

参数名称 类型 描述

StatusCode Number HTTP状态码。返回201表示成功,返回其它状态码表示失败。状态码详情请参见状态码。

Cookie String 授权的认证Cookie,用于进一步的API调用。

Payload JSON 返回消息。

返回Payload格式如下所示。

{ "Code": 201, "Message": "sucess|reason for failure"

644 文档版本:20200417

Page 657: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

}

完整示例

$ curl -i -c token.cookie -u admin:admin1234 -k -X POST https://127.0.0.1:9999/2019-09-30/auth/cookies

HTTP/1.1 201 CreatedServer: openresty/1.13.6.2Date: Thu, 31 Oct 2019 07:51:57 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: keep-aliveSet-Cookie: token=57e22d4f9fb237fcf5c0b59abf621ddeecde1ef740a84fbeb78540******bbe4; Max-Age=3600; Path=/

{"Code":201,"Message":"success"}

2.1.3.3.2 DeleteAuthCookie使用该接口删除认证Cookie。

请求语法

DELETE /2019-09-30/auth/cookies/TokenAuthorization: Authorization

请求参数

参数名称 类型 是否必选 描述

Token String 是 认证Cookie的Token。

Authorization String 是 基本授权信息。格式为 Basic base64(username:password)。

例如Basic Y2h5aW5n********NTY=。

返回语法

HTTP/1.1 StatusCodeContent-Type: application/json

Payload

返回参数

参数名称 类型 描述

StatusCode Number HTTP状态码。返回200表示成功,返回其它状态码表示失败。错误码详情请参见状态码。

Payload JSON 返回消息。

文档版本:20200417 645

Page 658: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

返回Payload格式如下所示。

{ "Code": 200, "Message": "sucess|reason for failure"}

完整示例

$ curl -i -u admin:admin1234 -k -X DELETE https://127.0.0.1:9999/2019-09-30/auth/cookies/57e22d4f9fb237fcf5c0b59abf621ddeecde1ef740a84fbeb78540******bbe4

HTTP/1.1 200 OKServer: openresty/1.13.6.2Date: Thu, 31 Oct 2019 07:57:23 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive

{"Code":200,"Message":"success"}

2.1.3.4 设备管理

2.1.3.4.1 GetThingProperties使用该接口获取指定设备的属性值。

请求语法

GET /2019-09-30/things/ProductKey/DeviceName/properties?identifiers=Identifier1&identifiers=Identifier2&... HTTP/1.1Cookie: Cookie

请求参数

参数名称 类型 是否必选 描述

ProductKey String 是 设备所属产品的唯一标识符。可从物联网平台控制台获取。

DeviceName String 是 设备的名称。可从物联网平台控制台获取。

Identifiers String 是 设备的属性标识符列表。最多可检索100条属性值。

Cookie String 是 调用CreateAuthCookie接口创建的认证Cookie。

返回语法

HTTP/1.1 StatusCodeContent-Type: application/json

646 文档版本:20200417

Page 659: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

Payload

返回参数

参数名称 类型 描述

StatusCode Number HTTP状态码。返回200表示成功,返回其它状态码表示失败。错误码详情请参见状态码。

Payload JSON 已获取的设备属性。

返回Payload格式如下所示。

{ "Code": 200, "Message": "sucess|reason for failure", "Data": { "Properties": { "Identifier1": "value1", "Identifier2": "value2", "Identifier3": "value3" }, "Timestamp": 1568262117344 }}

完整示例

$ curl -b token.cookie -k https://127.0.0.1:9999/2019-09-30/things/a1WabAEC***/N0hB9tiVWWZFMpALK***/properties?identifiers=LightSwitch

{"Data":{"Timestamp":1572512318420,"Properties":{"LightSwitch":1}},"Code":200,"Message":"success"}

2.1.3.4.2 SetThingProperties使用该接口为指定的设备设置属性。

请求语法

POST /2019-09-30/things/ProductKey/DeviceName/properties HTTP/1.1Cookie: Cookie

Payload

请求参数

参数名称 类型 是否必选 描述

ProductKey String 是 设备所属产品的唯一标识符。可从物联网平台控制台获取。

DeviceName String 是 设备的名称。可从物联网平台控制台获取。

文档版本:20200417 647

Page 660: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

参数名称 类型 是否必选 描述

Cookie String 是 调用CreateAuthCookie接口创建的认证Cookie。

Payload JSON 是 设置设备属性。格式请见表格下方请求Payload格式。

请求Payload格式如下所示。

{ "Properties": { "Identifier1": value1, "Identifier2": value2, "Identifier3": value3 ... }}

返回语法

HTTP/1.1 StatusCodeContent-Type: application/json

Payload

返回参数

参数名称 类型 描述

StatusCode Number HTTP状态码。返回200表示成功,返回其它状态码表示失败。错误码详情请参见状态码。

Payload JSON 底层属性设置接口返回的内容。

返回Payload格式如下所示。

{ "Code": 200, "Message": "sucess|reason for failure", "Data": { "Data": string|boolean|number|array|object, // A optional data that returned from the underlying set "Timestamp": 1568262117344 }}

完整示例

$ curl -b token.cookie -d '{"Properties":{"LightSwitch":0}}' -k -X POST https://127.0.0.1:9999/2019-09-30/things/a1WabAEC***/N0hB9tiVWWZFMpALK***/properties

648 文档版本:20200417

Page 661: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

{"Data":{"Data":[],"Timestamp":1572512468781},"Code":200,"Message":"success"}

2.1.3.4.3 CallThingServices使用该接口进行设备的服务调用。

请求语法

POST /2019-09-30/things/ProductKey/DeviceName/services HTTP/1.1Cookie: Cookie

Payload

请求参数

参数名称 类型 是否必选 描述

ProductKey String 是 设备所属产品的唯一标识符。可从物联网平台控制台获取。

DeviceName String 是 设备的名称。可从物联网平台控制台获取。

Cookie String 是 调用CreateAuthCookie接口创建的认证Cookie。

Payload JSON 是 被调用的服务的名称和参数。必须与在物联网平台控制台,为设备所属产品自定义产品功能时设置的,服务名称和参数保持一致。格式请见表格下方请求Payload格式。

请求Payload格式如下所示。

{ "Services": [ { "Name": "string", "Args": args // Optional arguments for the service. } ]}

返回语法

HTTP/1.1 StatusCodeContent-Type: application/json

文档版本:20200417 649

Page 662: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

Payload

返回参数

参数名称 类型 描述

StatusCode Number 接口返回码。返回200表示成功,返回其它状态码表示失败。错误码详情请参见状态码。

Payload JSON 调用服务的返回信息。

返回Payload格式如下所示。

{ "Code": 200, "Message": "sucess|reason for failure", "Data": { "Services": [ { "Name": "string", "Returns": { "Message": "success|reason for failure", "Data": string|boolean|number|array|object, // A optional data that returned from the underlying call services call. } } ], "Timestamp": 1568262117344 }}

完整示例

$ curl -i -b token.cookie -d '{"Services":[{"Name":"setColor","Args": {"color":"red"}}]}' -k -X POST https://127.0.0.1:9999/2019-09-30/things/a1WabAEC***/N0hB9tiVWWZFMpALK***/services

HTTP/1.1 200 OKServer: openresty/1.13.6.2Date: Thu, 31 Oct 2019 11:17:47 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive

{"Data":{"Services":[{"Name":"setColor","Returns":{"Message":"success","Data":[]}}],"Timestamp":1572520667899},"Code":200,"Message":"success"}

2.1.3.4.4 BulkActions使用该接口批量操作设备。

请求语法

POST /2019-09-30/things/bulk HTTP/1.1Cookie: Cookie

650 文档版本:20200417

Page 663: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

Payload

请求参数

参数名称 类型 是否必选 描述

Cookie String 是 调用CreateAuthCookie接口创建的认证Cookie。

Payload JSON 是 JSON对象,包含批量操作的动作(BulkAction)、操作对象(Things)及其相关参数。格式详情请参见表格下方Payload格式。

请求Payload格式如下所示。

{ "BulkAction": "string" "Things": [ { "ProductKey": "string", "DeviceName": "string", ... // Parameters for BulkAction } ]}

表 2-54: Payload参数说明

参数名称 类型 是否必选 描述

BulkAction String 是 指定请求的批量操作。 必须是如下指定参数之一:

• SetProperites:表示批量设置设备属性。

• GetProperites:表示批量获取设备属性。

• CallServices:表示批量调用设备服务。

• Watch:表示获取设备的某一组指定事件。

Things Array 是 JSON数组,包含操作对象及其对应的操作参数。格式详情请参见本文下方GetProperties、SetProperties、CallServices、Watch中请求Payload格式的Things参数。

返回语法

HTTP/1.1 StatusCode

文档版本:20200417 651

Page 664: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

Content-Type: ContentType

Payload

返回参数

参数名称 类型 描述

StatusCode Number HTTP状态码。返回200表示成功,返回其它状态码表示失败。错误码详情请参见状态码。

ContentType String 返回消息(Payload)的类型。取决于批量操作的动作(BulkAction)。

Payload JSON 批量操作的返回结果。

{ "Code": number, "Message": "success|reason for failure" "Data": {}}

表 2-55: Payload参数说明

参数名称 类型 描述

Code Number 接口返回码。返回200表示成功,返回其它状态码表示失败。错误码详情请参见状态码。

Message String 调用成功则返回success;调用失败则返回失败的原因。

Data Object 具体批量操作的返回结果。格式详情请参见本文下方GetProperties、SetProperties、CallServices、Watch中返回Payload格式的Data参数。

GetProperties

• 请求Payload格式

{ "BulkAction": "GetProperties", "Things": [ { "ProductKey": "string", "DeviceName": "string", "Identifiers": [ // Property Identifiers "string", "string", "string", ... ] } ]

652 文档版本:20200417

Page 665: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

}

• 返回Payload格式

Content-Type:application/json

{ "Code": number, "Message": "success|reason for failure", "Data": { "Results": [ { "ProductKey": "string", "DeviceName": "string", "Returns": { "Message": "success|reason for failure", "Data": { // The properties returned from the underlying get properties call. "Identifier1": value1, "Identifier2": value2, "Identifier3": value3 ... } }, } ], "Timestamp": 1568262117344 }}

• 完整示例

$ curl -i -b token.cookie -d '{"BulkAction":"GetProperties","Things":[{"ProductKey":"a1WabAEC***","DeviceName":"N0hB9tiVWWZFMpALK***","Identifiers":["LightSwitch"]}]}' -k -X POST https://127.0.0.1:9999//2019-09-30/things/bulk

HTTP/1.1 200 OKServer: openresty/1.13.6.2Date: Thu, 31 Oct 2019 11:30:40 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive

{"Data":{"Results":[{"Returns":{"Message":"success","Data":{"LightSwitch":1}},"DeviceName":"N0hB9tiVWWZFMpALK***","ProductKey":"a1WabAEC***"}],"Timestamp":1572521440288},"Code":200,"Message":"success"}

SetProperties

• 请求Payload格式

{ "BulkAction": "SetProperties", "Things": [ { "ProductKey": "string", "DeviceName": "string", "Properties": { "Identifier1": value1, "Identifier2": value2, "Identifier3": value3 ...

文档版本:20200417 653

Page 666: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

} } ]}

• 返回Payload格式

Content-Type:application/json

{ "Code": number, "Message": "success|reason for failure", "Data": { "Results": [ { "ProductKey": "string", "DeviceName": "string", "Returns": { "Message": "success|reason for failure", "Data": string|boolean|number|array|object // An optional data that returned from the underlying set properties call. }, } ], "Timestamp": 1568262117344 }}

• 完整示例

$ curl -i -b token.cookie -d '{"BulkAction":"SetProperties","Things":[{"ProductKey":"a1WabAEC***","DeviceName":"N0hB9tiVWWZFMpALK***","Properties":{"LightSwitch":1}}]}' -k -X POST https://127.0.0.1:9999//2019-09-30/things/bulk

HTTP/1.1 200 OKServer: openresty/1.13.6.2Date: Thu, 31 Oct 2019 11:46:53 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive

{"Data":{"Results":[{"Returns":{"Message":"success","Data":[]},"DeviceName":"N0hB9tiVWWZFMpALK***","ProductKey":"a1WabAEC***"}],"Timestamp":1572522413633},"Code":200,"Message":"success"}

CallServices

• 请求Payload格式

{ "BulkAction": "CallServices", "Things": [ { "ProductKey": "string", "DeviceName": "string", "Services": [ { "Name": "string", "Args": args // Optional arguments for the service. } ]

654 文档版本:20200417

Page 667: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

} ]}

• 返回Payload格式

Content-Type:application/json

{ "Code": number, "Message": "success|reason for failure", "Data": { "Results": [ { "ProductKey": "string", "DeviceName": "string", "Services": [ { "Name": "string", "Returns": { "Message": "success|reason for failure", "Data": string|boolean|number|array|object // An optional data that returned from the underlying call services call. } } ], } ], "Timestamp": 1568262117344 }}

• 完整示例

$ curl -i -b token.cookie -d '{"BulkAction":"CallServices","Things":[{"ProductKey":"a1WabAEC***","DeviceName":"N0hB9tiVWWZFMpALK***","Services":[{"Name":"setColor","Args":{"color":"red"}}]}]}' -k -X POST https://127.0.0.1:9999//2019-09-30/things/bulk

HTTP/1.1 200 OKServer: openresty/1.13.6.2Date: Thu, 31 Oct 2019 11:52:13 GMTContent-Type: application/json; charset=utf-8Transfer-Encoding: chunkedConnection: keep-alive

{"Data":{"Results":[{"Services":[{"Name":"setColor","Returns":{"Message":"success","Data":[]}}],"DeviceName":"N0hB9tiVWWZFMpALK***","ProductKey":"a1WabAEC***"}],"Timestamp":1572522733310},"Code":200,"Message":"success"}

Watch

• 请求Payload格式

{ "BulkAction": "Watch", "Things": [ { "ProductKey": "string", "DeviceName": "string", "Watches": "all|properties|events" // default is "all" }

文档版本:20200417 655

Page 668: 阿里云IoT Link Rack 一体机

开发指南 /  2 物联网边缘计算

]}

• 返回Payload格式

Content-Type:text/plain

- 常规消息

{ "Code": number, "Message": "success|reason for failure", "Data": { "ProductKey": "string", "DeviceName": "string", "Event": "string", "Args": {}, // Optional arguments along with the event. "Timestamp": 1568010749340 }}

- 心跳消息

{ "Code": 200, "Message": "heartbeat", "Data": { "Timestamp": 1568010749340 }}

• 完整示例

$ curl -b token.cookie -d '{"BulkAction":"Watch","Things":[]}' -k -X POST https://127.0.0.1:9999//2019-09-30/things/bulk

{"Data":{"Timestamp":1572510704112,"Event":"propertiesChanged","ProductKey":"a1t9b6Nn***","Args":{"MeasuredIlluminance":{"time":1572510704110,"value":400}},"DeviceName":"GjCb9LKXgcKXeluGJ***"},"Code":200,"Message":"success"}{"Data":{"Timestamp":1572510706116,"Event":"propertiesChanged","ProductKey":"a1t9b6Nn***","Args":{"MeasuredIlluminance":{"time":1572510706114,"value":300}},"DeviceName":"GjCb9LKXgcKXeluGJ***"},"Code":200,"Message":"success"}{"Data":{"Timestamp":1572510706117},"Code":200,"Message":"heartbeat"}{"Data":{"Timestamp":1572510708119,"Event":"propertiesChanged","ProductKey":"a1t9b6Nn***","Args":{"MeasuredIlluminance":{"time":1572510708118,"value":200}},"DeviceName":"GjCb9LKXgcKXeluGJ***"},"Code":200,"Message":"success"}

656 文档版本:20200417

Page 669: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3 物联网设备身份认证

3.1 我是设备厂商

3.1.1 设备厂商对接流程本篇文档介绍了设备厂商对接ID²的流程以及各流程的操作文档链接。

设备厂商对接流程如下:

操作项 适用范围

设备厂商对接准备工作 物联网设备生产厂商对接ID²

1.1 获取ProductKey(PK)

请根据ID²的接入模式,选择最适合您的操作文档。

操作项 适用范围

通过ID²控制台获取PK 通过客户自有IoT平台/第三方的业务系统对接ID²,而不通过阿里云物联网平台及其相关平台对接ID²

通过阿里云IoT平台获取PK 通过阿里云物联网平台及其相关平台对接ID²

1.2 获取ID²认证授权

请根据是否采购阿里云推荐的ID²安全芯片,选择最适合您的操作方式。

操作项 形态 适用范围

购买ID²认证授权 软件 采用KM、TEE的方案或者从其他渠道采购了ID²安全芯片

文档版本:20200417 657

Page 670: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

操作项 形态 适用范围

购买ID²安全芯片 软硬一体 阿里云推荐ID²安全芯片,每个芯片已烧录了一个5年有效的ID²。

3. 设备端适配

请根据ID²的载体类型,选择最适合您的操作文档。

操作项 适用范围

设备端适配:ID²-SE在AliOS Things上适配 载体类型为:ID²安全芯片

设备端适配:ID²-SE在三方OS上适配 载体类型为:ID²安全芯片

设备端适配:ID²-KM在Link Kit SDK上适配 无安全芯片

设备端适配:ID²在Link TEE上适配 载体类型为:TEE、阿里云IoT Link TEE

4. 自主验证

操作项 适用范围

自主验证 已经对接完服务端、设备端的ID²用户

3.1.2 确定方案您需要从以下的接入模式中,选择最适合您对接ID²的模式。

接入模式 适用范围

客户自有的IoT平台 您自己有相应的Server,无需依赖“阿里云物联网平台机器相关平台”进行IoT设备管理和业务对接。

第三方的业务系统 您已经使用了非阿里云的第三方平台作为Server来管理您的IoT设备。

通过阿里云物联网平台及其相关平台 您使用阿里云物联网平台、或阿里云IoT的任一系统进行IoT设备管理,包含:智能制造智能工业智能生活(生活物联网、飞燕)智能园区智能人居智能农业中的其他业务系统

您需要确定IoT设备的中ID²的载体类型,这将直接影响到IoT设备端的适配方式。

载体类型 说明 适用范围 安全性

SE 安全芯片 适用于配置了安全芯片的IoT设备

最高,支持国密

658 文档版本:20200417

Page 671: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

载体类型 说明 适用范围 安全性

TEE 可信执行环境 联网的嵌入式设备,在没有使用安全芯片时可以通过TEE来增强设备端的身份保护

KM 软沙盒安全载体,需要跟阿里云IoT安全走线下技术对接

适用于MCU/模组/嵌入式系统

3.1.3 对接准备工作

3.1.3.1 获取ProductKey

3.1.3.1.1 通过ID²控制台获取PK本篇文档适用于使用自建平台/第三方平台(非阿里云IoT平台及相关平台)接入ID²的用户。

1. 使用阿里云账号登录到ID²控制台。

2. 在左侧导航栏,选择使用管理 > 产品管理,再单击创建产品按钮。

3. 填写产品信息,点击创建产品。

4. 产品 创建成功后,新创建的产品会展示在产品列表中。从产品信息中,获取到新建产品的

ProductKey信息。

后续操作指引

• 服务端开发

操作项 适用范围

服务端开发和验证 通过自建平台/第三方平台对接ID²,而不通过阿里云物联网平台及其相关平台对接ID²。

• 设备端适配

请根据ID²的载体类型,选择最适合您的操作文档。

操作项 适用范围

设备端适配:ID²-SE在AliOS Things上适配 载体类型为:ID²安全芯片

设备端适配:ID²-SE在三方OS上适配 载体类型为:ID²安全芯片

设备端适配:ID²-KM在Link Kit SDK上适配 无ID²安全芯片

设备端适配:ID²在Link TEE上适配 载体类型为:Link TEE

文档版本:20200417 659

Page 672: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3.1.3.1.2 通过阿里云物联网平台获取PK本文档适用于通过阿里云物联网平台官方产品 开启和使用ID²。

阿里云物联网平台默认使用三元组对连接到物联网平台的设备身份进行验证。 ID²(Internet Device

ID)是一款独立付费的产品,ID²可以提供“设备-阿里云物联网平台”的双向身份认证能力,通过轻

量化的安全链路(iTLS)保障数据的安全性。

说明:

在创建产品时可以启用ID²。产品创建成功后使用ID²状态不可改变(不能从是变更为否,也不能

从否变更为是)。

一、在物联网平台创建产品

1. 在物联网平台控制台左侧导航栏,选择设备管理 > 产品,再在产品页,单击创建产品。

2. 填写产品信息。

说明:

认证方式选择为ID²。

二、在ID²管理控制台查看状态

进入ID²管理控制台,在ID²开放平台的产品列表中可以看到该产品,表示的您在物联网平台创建的新

产品已经开通了ID²服务。

获取到新建产品的ProdutKey。

3.1.4 服务端对接适用于ID²服务端对接。

本文档适用于:不经过阿里云物联网平台,IoT设备通过自建/第三方Server对接ID²的场景。

获取服务端SDK

您需要下载并集成适合您业务平台的服务端SDK。

2. 服务端接口对接

1. 安装依赖包。

参考SDK目录下aliyun-id2-sample/README,安装依赖包

2. 对接服务端接口。

服务端接口对接请参考《服务端API手册》,您也可以参考/aliyun-id2-sample中的实例代码。

3.1.5 设备端适配

660 文档版本:20200417

Page 673: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3.1.5.1 设备端适配:ID²-SE在三方OS上适配以平台stm32f103vb-fmse为例,使用的SE芯片名称为fm1280(国密芯片)。

1. OSA层适配

1.1 适配日志打印

以通用Linux OS系统函数为例:

1.1.1 实现ls_osa_print

void ls_osa_print(const char *fmt, ...){ va_list va_args; va_start(va_args, fmt); vprintf(fmt, va_args); va_end(va_args); }

1.1.2 实现ls_osa_snprintf

int ls_osa_snprintf(char *str, size_t size, const char *fmt, ...){ va_list args; int rc; va_start(args, fmt); rc = vsnprintf(str, size, fmt, args); va_end(args); return rc;}

1.2 适配内存管理

1.2.1 实现ls_osa_calloc

void *ls_osa_calloc(size_t nmemb, size_t size){ return calloc(nmemb, size);}

1.2.2 实现ls_osa_free

void ls_osa_free(void *ptr){ free(ptr);}

1.3 适配时间相关

1.3.1 实现ls_osa_msleep

void ls_osa_msleep(unsigned int msec)

文档版本:20200417 661

Page 674: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

{ usleep(msec * 1000);}

1.3.2 实现ls_osa_get_time_ms

long long ls_osa_get_time_ms(void){ struct timeval tv; long long ret = 0; gettimeofday(&tv, NULL); ret = tv.tv_sec * 1000 + tv.tv_usec / 1000; return ret;}

2. 设置编译工具链

修改make.rules,设置CROSS_COMPILE为用户平台对应的交叉工具链,例如:

CROSS_COMPILE := /usr/bin/arm-linux/arm-linux-

3. 编译并运行示例程序

在SDK根目录下,编译:

$ make clean$ make

生成./out/bin/id2_app 运行id2_app,日志如下:

<LS_LOG> id2_client_get_id 649: ID2: 000FFFFFDB1D8DC78DDCB800 <LS_LOG> id2_client_generate_authcode 170: ============ ID2 Validation Json Message ============: { "reportVersion": "1.0.0", "sdkVersion": "2.0.0", "date": "Aug 23 2019 18:17:13", "testContent": [{ ....... }] } <LS_LOG> id2_client_generate_authcode 186: =====>ID2 Client Generate AuthCode End.

出现上述日志,说明前面的OS接口和编译环境设置正确。下面开始SE芯片的适配和测试。

4. SE 驱动适配

4.1 适配SE芯片驱动接口

根据SE芯片驱动的控制方式,需要适配以下3个驱动接口。

662 文档版本:20200417

Page 675: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

4.1.1 适配se_open_session

irot_result_t se_open_session(void** handle){ // 示例代码:SE 初始化,打开SE芯片电源 fm_open_device(); fm_device_init(); fm_dev_power_on();}

4.1.2 适配se_transmit

irot_result_t se_transmit(void* handle, const uint8_t* cmd_apdu, const uint32_t cmd_len, uint8_t* rsp_buf, uint32_t* rsp_len){ // 示例代码:发送apdu指令,并获取response result = pfm_SeFunc->fm_apdu_transceive(xxx)}

4.1.3 适配se_close_session

irot_result_t se_close_session(void* handle){ // 示例代码:关闭设备,关闭SE芯片电源 fm_close_device(); fm_power_off();}

4.2 使能ID载体为SE

ID2 Client SDK默认编译时选择的是Demo为载体,适配好SE芯片后,需要配置工程切换为SE芯片为

载体。 进入make.settings修改CONFIG_ID2_KM_SE为y即可

#Link ID2 ConfigCONFIG_ID2_DEBUG := nCONFIG_ID2_OTP := nCONFIG_ID2_KM_SE := y ----> 修改为y

4.3 重新编译运行

$ make clean && make$ ./out/bin/id2_app

如果移植正确,会生成和Demo示例相同格式的Json格式的测试结果:

============ ID2 Validation Json Message ============: { "reportVersion": "1.0.0", "sdkVersion": "2.0.0", "date": "Aug 23 2019 18:17:13", "testContent": [{ .......

文档版本:20200417 663

Page 676: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

}] }

3.1.5.2 设备端适配:ID²-SE在AliOS Things上适配该文档介绍了通过AliOS Things集成ID²-SE的操作说明。以平台stm32f103vb-fmse为例,使用的国

密芯片为fm1280。

1. 适配SE芯片驱动接口

1.1 适配se_open_session

irot_result_t se_open_session(void** handle){ // 示例代码:SE 初始化,打开SE芯片电源 fm_open_device(); fm_device_init(); fm_dev_power_on();}

1.2 适配se_transmit

irot_result_t se_transmit(void* handle, const uint8_t* cmd_apdu, const uint32_t cmd_len, uint8_t* rsp_buf, uint32_t* rsp_len){ // 示例代码:发送apdu指令,并获取response result = pfm_SeFunc->fm_apdu_transceive(xxx)}

1.3 适配se_close_session

irot_result_t se_close_session(void* handle){ // 示例代码:关闭设备,关闭SE芯片电源 fm_close_device(); fm_power_off();}

进入AliOSThings/security/irot/se/aos.mk,添加对应SE芯片名称的文件夹fm1280,将SE芯片驱

动的实现代码放进去。并设置SE_CHIP_NAME为fm1280:aos.mk内容如下:

集成fm1280 SE驱动接口实现后,se文件夹结构如下:

664 文档版本:20200417

Page 677: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

2. AliOSThings平台配置和编译

2.1 确定设备名称,进入AliOSThings/board/stm32f103vb-fmse/

aos.mk,CONFIG_SYSINFO_DEVICE_NAME为ESP32,如下图:

2.2 在aos.mk中添加如下Config,设置CONFIG_LS_KM_SE为y,CONFIG_LS_ID2_OTP为n

2.3 编译id2测试appaos make id2_app@stm32f103vb-fmse -c config确定编译结果中依赖的库

是libkm_se

文档版本:20200417 665

Page 678: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

2.4 通过烧录工具烧写binary到平台并测试binary存放位置为:out/id2_app@stm32f103vb-fmse

/binary/[email protected]

3.1.5.3 设备端适配:ID²-KM在Link Kit SDK上适配适用范围:

• 使用Link kit SDK v2.3.0 、安全SDK v0.5集成安全功能(包括ID²、iTLS)

• 通过物联网平台创建的产品,节点类型为:网关类型、设备类型。

最佳实践说明: 1,本文所使用的产品,节点类型:网关类型; 2,网关设备下挂的子设备,通过设

备证书(三元组)的方式进行认证;

666 文档版本:20200417

Page 679: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

下载Link kit SDK

配置编译选项

通过 make menuconfig进入编译配置,编译选项中,使能 iTLS 和 网关example,

文档版本:20200417 667

Page 680: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

• 使能iTLS。

• 使能Gateway。

配置ProductKey和ProductSecret

修改gateway example code,把ProductKey和roduct Secret的值进行替换为您的产品对应的值。

Device Name和Device Secret可以自行命名,保证每个设备唯一即可。

$ vim examples/linkkit/linkkit_example_gateway.c

集成安全SDK库

如果您是针对嵌入式设备平台进行开发集成,请联系IoT安全团队沟通提供相关平台的安全库。

• 集成 安全SDK v0.5。

如果您直接使用ubuntu,那么可以确认下LinkKit C-SDK里面prebuilt目录下已经包含了预编译好

的安全SDK库,这样您可以进行自行编译集成:

prebuilt/

│├── ubuntu

668 文档版本:20200417

Page 681: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

│ ├── bin

│ │ └── kconfig-mconf

│ ├── include

│ └── libs

│ ├── libalicrypto.a

│ ├── libcurl.a

│ ├── libID²client.a

│ ├── libitls.a

│ ├── libkm.a

│ ├── libmbedcrypto.a

文档版本:20200417 669

Page 682: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

│ └── libplat_gen.a

• Link Kit v2.3.0 集成安全SDK v1.0/v2.0。

LinkKit接口图:

安全SDK 调用图:

1. 集成安全SDK相关库。

用安全相关库复制到prebuilt/$(os_name)/libs下。 复制完之后,prebuilt/$(os_name

)/libs下的库为:libicrypto.a libid2.a libitls.a libkm.a libls_hal.a libls_osa.a。其中

670 文档版本:20200417

Page 683: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

libicrypto.a libid2.a libitls.a libkm.a为安全团队提供的库, libls_osa.a libls_hal.a为厂商

适配的osa及hal层库。

2. 切换TLS的方式为ITLS连接方式。

执行命令:make menuconfig,然后启用ITLS。

3. 修改示例代码。

- 修改PRODUCT_KEY和PRODUCT_SECRET为产品的PRODUCT_KEY和PRODUCT_SECRET

。DEVICE_NAME保证产品唯一即可, DEVICE_SECRET可以为任意值。

- 修改iotkit-embedded/examples/iot.mk链接选项中,添加安全相关库依赖。

文档版本:20200417 671

Page 684: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

- 修改iotkit-embedded/src/ref-impl/hal/os/$os_name /HAL_Crypt_Linux.c, 适

配alicrypto 的接口。参考代码实现如下:

#include "iot_import.h"#include "ali_crypto.h"#define AES_BLOCK_SIZE 16#define KEY_LEN 16 // aes 128 cbc#define p_aes128_t p_HAL_Aes128_t#define PLATFORM_AES_ENCRYPTION HAL_AES_ENCRYPTION#define PLATFORM_AES_DECRYPTION HAL_AES_DECRYPTIONp_HAL_Aes128_t HAL_Aes128_Init( _IN_ const uint8_t *key, _IN_ const uint8_t *iv, _IN_ AES_DIR_t dir){ ali_crypto_result result; void * aes_ctx; size_t aes_ctx_size, alloc_siz; uint8_t * p; bool is_en = true; // encrypto by default if (dir == PLATFORM_AES_DECRYPTION) { is_en = false; } result = ali_aes_get_ctx_size(AES_CBC, &aes_ctx_size); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("get ctx size fail(%08x)", result); return NULL; } alloc_siz = aes_ctx_size + KEY_LEN * 2 + sizeof(bool); aes_ctx = HAL_Malloc(alloc_siz); if (aes_ctx == NULL) { HAL_Printf("kmalloc(%d) fail", (int)aes_ctx_size); return NULL; } memset(aes_ctx, 0, alloc_siz); p = (uint8_t *)aes_ctx + aes_ctx_size; memcpy(p, key, KEY_LEN); p += KEY_LEN; memcpy(p, iv, KEY_LEN); p += KEY_LEN; *((bool *)p) = is_en; return aes_ctx;}int HAL_Aes128_Destroy(_IN_ p_HAL_Aes128_t aes){ if (aes) { HAL_Free(aes); } return 0;}static int platform_aes128_encrypt_decrypt(p_HAL_Aes128_t aes_ctx, const void *src, size_t siz, void *dst, aes_type_t t){ ali_crypto_result result; size_t dlen, in_len = siz, ctx_siz; uint8_t * p, *key, *iv; bool is_en; if (aes_ctx == NULL) { HAL_Printf("platform_aes128_encrypt_decrypt aes_ctx is NULL"); return -1; }

672 文档版本:20200417

Page 685: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

result = ali_aes_get_ctx_size(AES_CBC, &ctx_siz); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("get ctx size fail(%08x)", result); return 0; } p = (uint8_t *)aes_ctx + ctx_siz; key = p; p += KEY_LEN; iv = p; p += KEY_LEN; is_en = *((uint8_t *)p); in_len <<= t == AES_CBC ? 4 : 0; dlen = in_len; result = ali_aes_init(t, is_en, key, NULL, KEY_LEN, iv, aes_ctx); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("ali_aes_init fail(%08x)", result); return 0; } result = ali_aes_finish(src, in_len, dst, &dlen, SYM_NOPAD, aes_ctx); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("aes_finish fail(%08x)", result); return -1; } return 0;}int HAL_Aes128_Cbc_Encrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t blockNum, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);}int HAL_Aes128_Cbc_Decrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t blockNum, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);}int HAL_Aes128_Cfb_Encrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t length, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);}int HAL_Aes128_Cfb_Decrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t length, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);}

文档版本:20200417 673

Page 686: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

4. 编译并运行example。

a. 运行make。

b. 编译成功后, 运行iotkit-embedded/output/release/bin文件夹下的mqtt-example,出

现以下log信息表示已成功切换成ITLS的链接方式。

出现以下log信息表示MQTT测试成功。

5. 调试。

如需更多的调试log,用debug 版本的itls及id2库,替换原prebuilt/ubuntu/libs文件夹中的

libitls.a和libid2.a。修改src/ref-impl/hal/ssl/itls/HAL_TLS_itls.c, 在该文件中添加宏定义

MBEDTLS_DEBUG_C, 并将DEBUG_LEVEL修改为4,例如:-#define DEBUG_LEVEL 0+#

define MBEDTLS_DEBUG_C+#define DEBUG_LEVEL 4,重新编译运行测试程序。

错误码:查看 iTLS错误码。

说明:

- 消息警告是在通信过程中,服务端发生异常,主动向设备端发送的消息通告。

- 消息类型是指iTLS Native返回的警告类型,Android LinkKit接口返回的值已做加权(10000

)处理。

674 文档版本:20200417

Page 687: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

编译

make编译链接生成gateway exampe程序,并且运行该网关例子程序。

./output/release/bin/linkkit-example-gw 5 auto

最后两个参数您可以手工输入,请参见实际代码。

查看日志:注意Host端口后缀为 itls.cn-shanghai.aliyuncs.com

查看日志:注意建联成功

文档版本:20200417 675

Page 688: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

验证

登录阿里云物联网平台,在设备管理 > 设备的设备列表下查看Device Name与gateway example代

码中设置的Device Name一致。如果一致,则该设备已经通过ID²认证并且接入物联网平台,您可以

进行后续设备topic订阅与推送等。

3.1.5.4 设备端适配:ID²在Link TEE上适配本篇文档适合使用Link TEE作为ID²载体的用户。

适用范围:

• 使用Link kit SDK v2.3.0 、安全SDK v2.0集成安全功能(包括ID²、iTLS)、使用Link TEE安全存

储ID²及相关的机密信息。

• 通过物联网平台创建的产品,节点类型为:网关类型。网关设备下挂的子设备,通过设备证

书(三元组)的方式进行认证。

1. 编译Link kit SDK

1.1 下载Link kit SDK

676 文档版本:20200417

Page 689: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

1.2 配置编译选项

通过 make menuconfig进入编译配置,编译选项中,使能 iTLS 和 网关example。

使能iTLS:

使能gateway:

1.3 ubuntu运行平台配置

将安全SDK的以下库放置于Linkkit SDK的prbuilt/ubuntu/libs目录中。安全SDK发布的库:

libicrypto.alibid2.alibitls.alibkm.alibls_hal.alibls_osa.a

将Link TEE发布的库置于Link SDK的prbuilt/ubuntu/libs目录中。

libtee_client.solibtee_internal.so

修改example/iot.mk,增加对安全SDK及Link TEE相关库的支持。

$(call Append_Conditional, LDFLAGS, \ -litls \

文档版本:20200417 677

Page 690: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

-lid2 \ -lkm \ -licrypto \ -lls_osa \ -lls_hal \ -ltee_client \ -ltee_internal \

修改mqtt_example.c中的PRODUCT_KEY,PRODUCT_SECRET为您申请购买后可用的值,

DEVICE_NAME, DEVICE_SECRET按照您自己的定义进行命名。

说明:

DEVICE_NAME 需要和您在阿里云物联网平台中设定的名称一致,保证名称唯一。

#define PRODUCT_KEY "a1Oxxxxx"#define PRODUCT_SECRET "i11xxxxxxxxxxx"#define DEVICE_NAME "test_gateway"#define DEVICE_SECRET "i11fxxxxxxxxxxxxxxxxxxxxxx"

修改iotkit-embedded/src/ref-impl/hal/os/$os_name /HAL_Crypt_Linux.c, 适配alicrypto 的接

口。 参考代码实现如下:

#include "iot_import.h"#include "ali_crypto.h"#define AES_BLOCK_SIZE 16#define KEY_LEN 16 // aes 128 cbc#define p_aes128_t p_HAL_Aes128_t#define PLATFORM_AES_ENCRYPTION HAL_AES_ENCRYPTION#define PLATFORM_AES_DECRYPTION HAL_AES_DECRYPTIONp_HAL_Aes128_t HAL_Aes128_Init( _IN_ const uint8_t *key, _IN_ const uint8_t *iv, _IN_ AES_DIR_t dir){ ali_crypto_result result; void * aes_ctx; size_t aes_ctx_size, alloc_siz; uint8_t * p; bool is_en = true; // encrypto by default if (dir == PLATFORM_AES_DECRYPTION) { is_en = false; } result = ali_aes_get_ctx_size(AES_CBC, &aes_ctx_size); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("get ctx size fail(%08x)", result); return NULL; } alloc_siz = aes_ctx_size + KEY_LEN * 2 + sizeof(bool); aes_ctx = HAL_Malloc(alloc_siz); if (aes_ctx == NULL) { HAL_Printf("kmalloc(%d) fail", (int)aes_ctx_size); return NULL; } memset(aes_ctx, 0, alloc_siz); p = (uint8_t *)aes_ctx + aes_ctx_size; memcpy(p, key, KEY_LEN); p += KEY_LEN; memcpy(p, iv, KEY_LEN);

678 文档版本:20200417

Page 691: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

p += KEY_LEN; *((bool *)p) = is_en; return aes_ctx;}int HAL_Aes128_Destroy(_IN_ p_HAL_Aes128_t aes){ if (aes) { HAL_Free(aes); } return 0;}static int platform_aes128_encrypt_decrypt(p_HAL_Aes128_t aes_ctx, const void *src, size_t siz, void *dst, aes_type_t t){ ali_crypto_result result; size_t dlen, in_len = siz, ctx_siz; uint8_t * p, *key, *iv; bool is_en; if (aes_ctx == NULL) { HAL_Printf("platform_aes128_encrypt_decrypt aes_ctx is NULL"); return -1; } result = ali_aes_get_ctx_size(AES_CBC, &ctx_siz); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("get ctx size fail(%08x)", result); return 0; } p = (uint8_t *)aes_ctx + ctx_siz; key = p; p += KEY_LEN; iv = p; p += KEY_LEN; is_en = *((uint8_t *)p); in_len <<= t == AES_CBC ? 4 : 0; dlen = in_len; result = ali_aes_init(t, is_en, key, NULL, KEY_LEN, iv, aes_ctx); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("ali_aes_init fail(%08x)", result); return 0; } result = ali_aes_finish(src, in_len, dst, &dlen, SYM_NOPAD, aes_ctx); if (result != ALI_CRYPTO_SUCCESS) { HAL_Printf("aes_finish fail(%08x)", result); return -1; } return 0;}int HAL_Aes128_Cbc_Encrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t blockNum, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);}int HAL_Aes128_Cbc_Decrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t blockNum, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, blockNum, dst, AES_CBC);}

文档版本:20200417 679

Page 692: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

int HAL_Aes128_Cfb_Encrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t length, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);}int HAL_Aes128_Cfb_Decrypt( _IN_ p_HAL_Aes128_t aes, _IN_ const void *src, _IN_ size_t length, _OU_ void *dst){ return platform_aes128_encrypt_decrypt(aes, src, length, dst, AES_CFB128);}

1.4 编译,运行make,编译成功后生成linkkit-example-gw。

2. linkkit-example-gw测试验证

在output/release/bin 文件夹下,运行命令:

LD_LIBRARY_PATH=../lib/ ./linkkit-example-gw

出现以下log信息表示已成功切换成itls的链接方式,并使用Link TEE作为安全存储服务。

出现以下log信息表示mqtt测试成功。

3.1.6 自主验证全链路的自主验证。

该文档介绍了如何利用”设备端适配验证“完成ID²全链路的调试验证。

您完成ID²在设备端的适配后,可以通过ID²”设备端适配验证工具“验证ID²的设备认证、解密功能。

设备端适配验证工具适用于不同的载体(如TEE,SE,MCU),流程如下。

680 文档版本:20200417

Page 693: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

1.1 获取设备端调试工具。

1.2 编译生成自主验证的固件(id2_app)

1.3 自主验证的固件烧录到设备,运行得到调试结果:

3. 在设备端解密

3.1 获取服务端生成的密文

3.2 在设备端导入密文

3.3 在设备端进行解密的验证

• 重新编译生成固件(id2_app)

• 烧录固件到设备

• 运行固件,进行解密验证

文档版本:20200417 681

Page 694: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3.2 我是芯片/模组厂商

3.2.1 芯片/模组厂商 对接流程本篇文档介绍了芯片/模组厂商烧录ID²的流程以及各流程的操作文档链接。

芯片/模组厂商 烧录ID²流程如下:

操作项 适用范围

芯片/模组厂商烧录准备工作 芯片厂商/模组厂商烧录ID²前的准备工作

2. 设备端适配

请根据ID²的载体类型,选择最适合您的操作文档。

682 文档版本:20200417

Page 695: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

操作项 适用范围

使用AliOS Things 对接ID²-SE 芯片厂商

其他OS对接ID²-SE 芯片厂商

使用AliOS Things对接ID²-KM 模组厂商

使用其他OS对接ID²-KM 模组厂商

3. 烧录ID²

请根据ID²的载体类型,选择最适合您的操作文档。

操作项 适用范围

烧录ID²到芯片 芯片厂商

烧录ID²到模组 模组厂商

4. 自主验证

操作项 适用范围

自主验证 已经对接完服务端、设备端的ID²用户

5. 产线审核

操作项 适用范围

产线审核 已经完成烧录对接和产线验证,申请产线烧录ID²的资质

3.2.2 设备端对接

3.2.2.1 模组厂商 对接ID²

3.2.2.1.1 使用AliOS Things对接ID²-KM本文档适用于AliOS Things v3.0&安全 SDK v2.0

1. 适配KM HAL层 首先确定设备名称和架构名称,在AliOSThings/board/<设备名称>/aos.mk下

面,设备名称为CONFIG_SYSINFO_DEVICE_NAME,架构名称为HOST_ARCH。 以esp32devkitc为

例:进入AliOSThings/board/esp32devkitc/aos.mk, CONFIG_SYSINFO_DEVICE_NAME为ESP32,

ARCH名称为xtensa,创建对应的HAL层的方式为:

(1)创建文件夹 security/ls_hal/km/esp32

文档版本:20200417 683

Page 696: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

(2)修改security/ls_hal/aos.mk添加esp32文件编译

ifeq ($(CONFIG_SYSINFO_DEVICE_NAME), ESP32)$(NAME)_SOURCES += ./km/esp32/ls_hal_km.cendif

(3)添加文件security/ls_hal/km/esp32/ls_km_hal.c并实现Soft-KM HAL接口。 需要适配的

HAL接口为:

int ls_hal_get_dev_id(uint8_t *dev_id, uint32_t *id_len)int ls_hal_open_rsvd_part(int flag)int ls_hal_write_rsvd_part(int fd, uint32_t offset, void *data, uint32_t data_len)int ls_hal_read_rsvd_part(int fd, uint32_t offset, void *buffer, uint32_t read_len)int ls_hal_read_rsvd_part(int fd, uint32_t offset, void *buffer, uint32_t read_len)

2. 添加km 库 检查平台架构 HOST_ARCH ,若该架构已存在于security/irot/km/lib 中,则忽略该

步骤,若不存在,则需联系安全团队提供相应的libkm.a 库。 以esp32devkitc 为例,HOST_ARCH

为xtensa: (1)security/irot/km/lib下新建xtensa文件夹, 文件夹名与HOST_ARCH 保持一致。

(2)拷贝libkm.a 到该文件夹中。

3. 添加prov库 如果ID²是通过产线烧录到设备端, 则需要联系安全团队提供libprov.a 库,并放到

security/prov/lib/<HOST_ARCH>。 以esp32devkitc平台为例,在 security/prov/lib/下新建

xenta文件夹,拷贝libprov.a 到该文件夹中。

3.2.2.1.2 使用其他OS对接ID²-KM该文档介绍了如何在其他的第三方OS上通过ID²-KM的方式完成设备端的适配。

1.1 首先适配OSA基础功能接口。API接口详情参照《安全SDK API》需要芯片/模组厂商实现的接口

如下:

void ls_osa_print(const char *fmt, …)int ls_osa_snprintf(char *str, size_t size, const char *fmt, ...)void *ls_osa_malloc(size_t size)void ls_osa_free(void *ptr)long long ls_osa_get_time_ms(void)

1.2 如果需要用到多线程的场景,则需要实现OSA多线程管理接口,否则可以直接返回0(对int类型

的函数)或者直接返回(对void类型函数)。 需要芯片/模组厂商实现的接口如下:

int ls_osa_mutex_create(void **mutex)void ls_osa_mutex_destroy(void *mutex)int ls_osa_mutex_lock(void *mutex)int ls_osa_mutex_unlock(void *mutex)

684 文档版本:20200417

Page 697: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

1.3 如果需要使用安全SDK 安全连接服务(iTLS),则需要实现OSA网络操作接口,否则可以直接返回

0。 需要芯片/模组厂商实现的接口如下:

int ls_osa_net_connect(const char *host, const char *port, int type)void ls_osa_net_disconnect(int fd)int ls_osa_net_send(int fd, unsigned char *buf, size_t len, int *ret_orig)int ls_osa_net_recv(int fd, unsigned char *buf, size_t len, int timeout, int *ret_orig)

int ls_hal_get_dev_id(uint8_t *dev_id, uint32_t *id_len)int ls_hal_open_rsvd_part(int flag)int ls_hal_write_rsvd_part(int fd, uint32_t offset, void *data, uint32_t data_len)int ls_hal_read_rsvd_part(int fd, uint32_t offset, void *buffer, uint32_t read_len)int ls_hal_close_rsvd_part(int fd)

说明:

如果您不需要1.2、1.3中的接口,为防止编译过程中出现对应symbol找不到的问题,请在实现中直

接return或者返回0。 代码示例(以网络接口为例):

/* for void type, directly return */void ls_osa_net_disconnect(int fd) { return;}/* for int type, return 0 */int ls_osa_net_connect(const char *host, const char *port, int type) { return 0;}

2. 适配验证

编译并运行hal_test,显示结果如下:

hal_test 打印结果<LS_LOG> PL ERR ls_hal_get_dev_id 167: short buffer id len is 1<LS_LOG> PL ERR ls_hal_get_dev_id 167: short buffer id len is 1<LS_LOG> PL ERR ls_hal_write_rsvd_part 245: bad param<LS_LOG> PL ERR ls_hal_read_rsvd_part 283: read failed real read len is -1<LS_LOG> INF hal_km_rsvd_part_stress_test 357: write 1K data total time: 1.000000ms, av_time: 0.001000ms<LS_LOG> INF hal_km_rsvd_part_stress_test 372: read 1K data total time: 1.000000ms, av_time: 0.001000ms<LS_LOG> INF hal_km_test 434: ============================> HAL KM Test Pass.

<LS_LOG> INF hal_crypto_test 43: HAL Hash Test:<LS_LOG> INF hal_hash_test 140: SHA1 test success!<LS_LOG> INF hal_hash_test 190: SHA256 test success!<LS_LOG> INF hal_hash_test 239: md5 test success!<LS_LOG> INF hal_hash_test 249: =========================> HAL Hash Test Pass.

<LS_LOG> INF hal_crypto_test 49: HAL Rand Test:<LS_LOG> INF hal_rand_test 22: ==========================> HAL Rand Test Pass.

文档版本:20200417 685

Page 698: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

<LS_LOG> INF hal_crypto_test 55: HAL AES Test:<LS_LOG> INF hal_aes_test 682: HAL AES ECB Test:<LS_LOG> INF _aes_ecb_test 445: AES_ECB_128 test success!<LS_LOG> INF _aes_ecb_test 445: AES_ECB_192 test success!<LS_LOG> INF _aes_ecb_test 445: AES_ECB_256 test success!<LS_LOG> INF hal_aes_test 691: HAL AES CBC Test:<LS_LOG> INF _hal_aes_cbc_test 519: AES_CBC_128 test success!<LS_LOG> INF _hal_aes_cbc_test 519: AES_CBC_192 test success!<LS_LOG> INF _hal_aes_cbc_test 519: AES_CBC_256 test success!<LS_LOG> INF hal_aes_test 700: HAL AES CTR Test:<LS_LOG> INF _hal_aes_ctr_test 591: AES_CTR_128 test success!<LS_LOG> INF _hal_aes_ctr_test 591: AES_CTR_192 test success!<LS_LOG> INF _hal_aes_ctr_test 591: AES_CTR_256 test success!<LS_LOG> INF hal_aes_test 709: HAL AES CFB Test:<LS_LOG> INF _hal_aes_cfb_test 665: AES_CFB_128 test success!<LS_LOG> INF _hal_aes_cfb_test 665: AES_CFB_192 test success!<LS_LOG> INF _hal_aes_cfb_test 665: AES_CFB_256 test success!<LS_LOG> INF hal_aes_test 720: =============================> HAL AES Test Pass.

<LS_LOG> INF hal_crypto_test 61: HAL RSA Test:<LS_LOG> INF _hal_encrypt_decrypt 150: RSA encrypt/decrypt test success<LS_LOG> INF hal_rsa_test 192: =============================> HAL RSA Test Pass.

3.2.2.2 芯片厂商 对接ID²

3.2.2.2.1 使用AliOS Things 对接ID²-SE该文档介绍了通过AliOS Things集成ID²-SE(ID²安全芯片)的操作说明。 以平台stm32f103vb-

fmse为例,使用的国密芯片为fm1280:

1.确定设备名称,进入AliOSThings/board/stm32f103vb-fmse/aos.mk,CONFIG_SYS

INFO_DEVICE_NAME为ESP32,如下图:

2.在aos.mk中添加如下Config,设置CONFIG_LS_KM_SE为y,CONFIG_LS_ID2_OTP为n

3.进入AliOSThings/security/irot/se/aos.mk,添加对应SE芯片名称的文件夹fm1280,将SE芯片

驱动的实现代码放进去。并设置SE_CHIP_NAME为fm1280:aos.mk内容如下:

集成fm1280 SE驱动接口实现后,se文件夹结构如下:

686 文档版本:20200417

Page 699: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

4.编译id2测试app aos make id2_app@stm32f103vb-fmse -c config

确定编译结果中依赖的库是libkm_se

5.通过烧录工具烧写binary到平台并测试

文档版本:20200417 687

Page 700: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

binary存放位置为:out/id2_app@stm32f103vb-fmse/binary/id2_app@stm32f103vb-fmse.

bin

3.2.2.2.2 其他OS对接ID²-SE本文档介绍了如何通过第三方OS(非AliOS Things)、ID² client SDK完成ID²的对接。

我们为SE安全芯片厂商提供了开源、精简的ID² Client SDK,以便SE安全芯片厂商能够进行自主移植

并进行SE功能验证。

2. 适配ID² Client SDK

void ls_osa_print(const char *fmt, …)int ls_osa_snprintf(char *str, size_t size, const char *fmt, ...)void *ls_osa_malloc(size_t size)void ls_osa_free(void *ptr)long long ls_osa_get_time_ms(void)

ID² Client SDK与安全SDK共同一套API手册。

3. Demo 验证测试

为了便于芯片厂商理解ID²功能接口的作用,在ID² Client SDK中提供了一个简单的Demo实现(用来

保存样例ID²密钥,并且完成测试程序id2_app的功能验证)。 芯片厂商拿到该开源的ID² client SDK

,适配好以上OSA各个基础api后,可以基于这个Demo方式,编译并链接出完整的id2_app,进行

ID²接口功能的调试和验证。

但最终还是需要切换到SE安全芯片的方式,具体方式参考下面章节内容。

4. 第三方OS集成SE最佳实践

以平台stm32f103vb-fmse为例,使用的SE芯片名称为fm1280(国密芯片)。

688 文档版本:20200417

Page 701: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

4.1 进入security/irot/se,添加对应SE芯片名称的文件夹fm1280,将SE芯片驱动的实现代码

se_driver.c(以及相关依赖文件)放进去。

注: SE芯片驱动需要对接的接口为:se_open_session/se_transmit/se_close_session,具体参

考 SE 芯片驱动API文档。

4.2 修改security/irot/se/Makefile,指向fm1280 SE驱动实现代码。

4.3 修改根目录Makefile 切换demo到se目录。

文档版本:20200417 689

Page 702: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

4.4 编译id2_app直接在根目录下:make cleanmake。

4.5 运行id2_app测试。

3.2.3 烧录ID²

3.2.3.1 烧录ID²到模组该文档帮助芯片/模组厂商、设备厂商在产线环境将ID²安全的烧录到设备中。

主要包含以下内容:

• 从ID² Server端获取ID²,保存到PC/服务器。

• 从PC/服务器将ID²保存到模组上。

• 通过烧录工具将ID²烧录到模组的安全区。

该文档的适用范围:

• 通过阿里云IoT提供的安全SDK对接。

• 载体是Soft-KM(Key Management)。

• ID²通过产线烧录的方式预制。

1.1 使用说明

1.1.1 ID²烧录许可申请

1.1.2 ID²烧录SDK集成

可先基于提供的示例代码(sample), 进行代码调试和测试。

690 文档版本:20200417

Page 703: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

1.1.3 配置烧录端口数和许可证文件路径(ds_sample.c->ds_init)

1) 烧录端口数:ID²烧录数据并发拉取的数目。

2) 许可证文件路径:licenseConfig.ini相对库文件的路径。

1.1.4 创建工程,编译生成烧录测试工具

1)ID²烧录数据默认生成在当前bin目录,且同线程下生成的文件名称相同。

1.1.5 配置许可证文件(licenseConfig.ini)

其中:

配置项 值

serverType 固定值1 - factory mode

ID2SyncPolicy 获取ID²数据的策略。

0:对应异步(速度较快,但会有一定的浪

费)。

1:对应同步(按需获取数据,不会产生浪

费,使用于网络良好的场景)。

license: 已经申请到的许可证编号。。

factPriKey: 产线私钥,用于解密服务端下发的ID²密钥,对应的公钥用于许可证申请。

1.1.6 配置日志文件(log.conf)

1. 日志配置文件(log.conf)需与库在相同目录,生成的日志以日期命名,如2017-10-23.log。

2. 配置项说明:

配置项 值

path: 日志输出路径

文档版本:20200417 691

Page 704: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

配置项 值

level: 日志输出的级别:

NONE_O: 不输出日志

INFO_O: 输出INFO类型的日志

DEBUG_O: 输出DEBUG类型的日志

ERROR_O: 输出ERROR 类型的日志

ALL: 输出所有类型的日志

1.2 ID²数据拉取流程

2. ID²烧录数据的导入

主要完成将拉取的ID²烧录数据从PC端写入到设备端(动态内存/静态存储区)。

PC端和设备端ID²烧录数据传输的方式由厂商自行确定,每个设备只传入和写入一个ID²烧录数据,且

保证传输过程数据的正确性和完整性。

692 文档版本:20200417

Page 705: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3. ID²数据的烧录和测试

ID²数据烧录主要是指通过设备端Prov模块完成数据的解析和ID²数据的安全保护和存储。

ID²烧录测试用于在产线上对ID²烧录结果的验证。

ID²数据烧录和测试触发方式由厂商确定,具体流程可参考如下:

3.1 获取模组上烧录结果

调用prov_get_prov_res函数。

返回值 结果

0 烧录成功

文档版本:20200417 693

Page 706: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

返回值 结果

非0 烧录失败,需要进行烧录

3.2 数据烧录

调用prov_item函数烧录数据,其中item_name设为ITEM_NAME_ID2, data标明ID²烧录数据在内存

的地址,data_len标明烧录数据的字节长度。

3.3 获取模组上烧录结果

再次调用prov_get_prov_res函数。

返回值 结果

0 烧录成功

非0 烧录失败

3.2.3.2 烧录ID²到芯片ID²产线烧录SDK是由阿里开发和维护,提供给合作厂商,用于集成到厂商烧录工具,完成ID²烧录数

据的拉取。

Release Package:

目录 说明 备注

sdk-lib 库文件 ID² SDK库,以及依赖的库。

694 文档版本:20200417

Page 707: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

目录 说明 备注

sdk-sample 示例代码 ID²数据拉取,ID²烧录回执。

genkeypairs.jar RSA1024公私钥生成工具 -

1.1 public static String retrieveID²(String apiVersion, String count, String license, String sign)

• 功能:ID²数据拉取

• 参数:

apiVersion ID2版本,固定值“1.0.0”

count 请求个数,一次最多可请求30个。

license ID²烧录许可编号,由厂商向阿里申请获得。

sign ID²烧录许可私钥签名,签名数据 = apiVersion + count + license。

• 返回值:

结果 返回值

成功 {“code”: 200,“msg”: “succcess”,“value”: [ { “id2”: “xxx”, “privateKey”: “xxx”, -> ID密钥,厂商公钥加密。 “kcv”: “xxx” -> 密钥校验,ID密钥加密(RSA/3DES) : // 1.RSA/ECB/PKCS1Padding // 2.AES/ECB/PKCS5Padding // 3.DESede/ECB/PKCS5Padding } ]}

失败 { “code”: xxx, ->错误码 “msg”: “xxx”, ->错误信息 “value”: null}

1.2 public static String returnID²ByTools(String apiVersion, String ID², String cipherSuite,

String keySource, String sign)

• 功能:ID²烧录回执

• 参数:

apiVersion ID2版本,固定值“1.0.0”

id2 ID2 ID 字符串0

cipherSuite 算法类型,本版只支持模式一,设定为固定值“0”

文档版本:20200417 695

Page 708: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

apiVersion ID2版本,固定值“1.0.0”

keySource 密钥类型,“0” - ID2密钥,“1” - ID²烧录许可私钥

sign 签名结果,签名数据 = id2, 签名密钥根据keySource选择

• 返回值:

结果 返回值

成功 { "code": 200, "msg": "success", "value": true}

失败 { "code": xxx, -> 错误码 "msg": "xxx", -> 错误信息 "value": true}

2. 使用说明

2.2 ID²烧录SDK集成: 可先基于提供的示例代码, 进行代码调试和测试。

2.3 烧录许可和模式配置: ID²Sample.java:

1)配置count的值,选择每次请求获取ID²的数量(最大30)。

2)配置keySource的值,选择ID²烧录回执使用的密钥:

产线上可以获取ID²密钥明文 keySource = "0"(ID²密钥)

产线上无法获取ID²密钥明文 keySource = "1"(厂商私钥)

3)配置烧录许可和厂商私钥:

696 文档版本:20200417

Page 709: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

license ID²烧录许可

licensePrivKey 厂商烧录私钥,对应于申请许可提交的公钥

3.2.4 自主验证该文档介绍了如何利用”设备端适配验证“完成ID²全链路的调试验证。

您完成ID²在设备端的适配后,可以通过ID²”设备端适配验证工具“验证ID²的设备认证、解密功能。

设备端适配验证工具适用于不同的载体(如TEE,SE,MCU),流程如下。

1.1 获取设备端调试工具。

1.2 编译生成自主验证的固件(id2_app)

1.3 自主验证的固件烧录到设备,运行得到调试结果:

3. 在设备端解密

3.1 获取服务端生成的密文。

3.2 在设备端导入密文。

文档版本:20200417 697

Page 710: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3.3 在设备端进行解密的验证。

• 重新编译生成固件(id2_app)。

• 烧录固件到设备。

• 运行固件,进行解密验证。

3.2.5 产线审核本文介绍产线审核流程。

1.1 新增产线

登录ID²芯片接入平台,在产线列表中点击“新增产线”。

698 文档版本:20200417

Page 711: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

1.2 填写产线信息

在页面中填写产线的真实信息,并选择一款芯片,填写芯片的相关测试数据,点击“确认”。

1.3 确认烧录测试完成

您可以下载产线SDK来完成产线预烧录的测试。如果您已经完成了烧录的测试,请跳过此步骤。

文档版本:20200417 699

Page 712: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

2. 提交审核

2.1 上传审核资料

完成产线的预烧录测试后,您需要在以下页面上传产线预烧录日志和烧录现场的3张照片。

该页面也可以在产线列表点击“提交审核”进入。

2.2 审核结果

700 文档版本:20200417

Page 713: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

预烧录日志和烧录现场的3张照片全部上传之后,您需要等待阿里云IoT的审核,请通知您和阿里云

IoT联系的接口人。审核通过后,产线就具备了ID²安全芯片的烧录资质了。

3.3 API参考

3.3.1 设备端API手册本文档描述ID²接口在设备端如何使用,ID² Client SDK封装了底层对ID²载体、接口的操作细节,应

用只需调用该接口进行相关操作,即可访问设备端ID²服务。

函数原型

int id2_client_init(void);

功能描述

ID² Client SDK初始化,使用ID²设备端其它API之前,首先需调用该API进行初始化操作。

参数描述

返回值

0: 成功

二、获取ID²

函数原型

int id2_client_get_id(uint8_t* id, uint32_t* len);

功能描述

获取ID²字串

文档版本:20200417 701

Page 714: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

参数描述

名称 输入/输出 描述

id out 存放ID²字串的起始地址,长度不小于24字节

len in/out 入参为参数id²的buf长度,出参为ID²字串的实际长度

返回值

0: 成功

三、获取设备认证码--挑战应答模式

函数原型

int id2_client_get_challenge_auth_code(const char* challenge, const uint8_t* extra, uint32_t extra_len, uint8_t* auth_code, uint32_t* auth_code_len);

功能描述

基于挑战应答模式生成设备端认证码,可以有选择性的携带额外数据(extra),携带的extra参与设

备认证码的签名运算。

参数描述

名称 输入/输出 描述

challenge 输入 挑战字起始地址,经SP Server从ID² Server获取

extra 输入 额外数据起始地址,可选,由Device和SP Server根据某种约定分别生成

extra_len 输入 额外数据长度,最大长度512字节

auth_code 输出 设备认证码起始地址,长度不小于256字节

auth_code_len 输入/输出 入参为参数auth_code的buf长度,出参为设备认证码的实际长度

返回值

0: 成功

702 文档版本:20200417

Page 715: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

交互流程图

四、获取设备认证码--时间戳模式

函数原型

int id2_client_get_timestamp_auth_code(const char* timestamp, const uint8_t* extra, uint32_t extra_len, uint8_t* auth_code, uint32_t* auth_code_len);

文档版本:20200417 703

Page 716: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

功能描述

基于时间戳模式生成设备端认证码,可以有选择性的携带额外数据(extra),携带的extra参与设备

认证码的签名运算。时间戳可以由设备端RTC生成,或者由SP携带发送给设备端。

参数描述

timestamp 输入 当前系统时间(从1970年1月1日午夜开始经过的毫秒数),字符串形式表示,如”

1500954672653” extra 输入 额外数据起始地址,可选,由Device和SP Server根据某种约定分别

生成 extra_len 输入 额外数据长度,最大长度512字节 auth_code 输出 设备认证码起始地址,长度

不小于256字节 len 输入/输出 入参为参数auth_code的buf长度,出参为设备认证码的实际长度

返回值

0: 成功

704 文档版本:20200417

Page 717: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

交互流程图

五、ID²解密

函数原型

int id2_client_decrypt(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t* out_len);

功能描述

使用ID²解密指定的数据

文档版本:20200417 705

Page 718: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

参数描述

名称 输入/输出 描述

in 输入 待解密的数据起始地址,数据如果是base64编码,需要先进行base64解码

in_len 输入 待解密的数据长度,长度不超过512字节

out 输出 解密后的数据起始地址

out_len 输入/输出 入参为参数out的buf长度,出参为解密后的数据长度

返回值

0: 成功

六、获取设备烧录状态

函数原型

irot_result_t id2_client_get_prov_stat(bool *is_prov);

功能描述

获取设备端ID²的烧录状态

参数描述

名称 输入/输出 描述

is_prov 输出 布尔类型,存放ID²的烧录状态

返回值

0: 成功

七、获取设备空发认证码

函数原型

irot_result_t id2_client_get_otp_auth_code(const uint8_t *token, uint32_t token_len, uint8_t *auth_code, uint32_t *len);

功能描述

获取设备端ID²空发的认证码

706 文档版本:20200417

Page 719: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

参数描述

名称 输入/输出 描述

token 输入 ID² Server颁发的空发token, 按产品划分

token_len 输入 ID²空发token的长度,固定值32字节

auth_code 输出 ID²空发认证码的内存,长度小于256字节

len 输入/输出 入参为auth_code的内存大小,出参为认证码的实际长度

返回值

0: 成功

八、烧录空发数据

函数原型

irot_result_t id2_client_load_otp_data(const uint8_t *otp_data, uint32_t len);

功能描述

烧录空发数据到设备中

参数描述

名称 输入/输出 描述

otp_data 输入 ID² Server下发的空发数据包(加密保护)

len 输入 ID²空发数据包的长度

返回值

0: 成功

3.3.2 服务端API手册服务端API调用说明如下。

接口名称

verify

文档版本:20200417 707

Page 720: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

访问地址

需要POP SDK支持,endpoint domain: id2.cn-shanghai.aliyuncs.com

功能描述

ID² 运行时认证接口.

请求参数

名称 类型 是否必须 描述

apiVersioin String 是 api版本号,当前取值1.1.2

id2 String 是 ID²标识

authCode String 是 设备端生成的认证码

extra String 否 与认证码关联的辅助认证数据

productKey String 是 产品标识,从ID²控制台的产品列表中获取

返回值

成功: { "code":200, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": true, "data": true } 失败: { "code":33, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": false }

错误码

参见《错误码》

二、服务端认证并加密接口

接口名称

verifyAndEncrypt

访问地址

需要POP SDK支持,endpoint domain: id2.cn-shanghai.aliyuncs.com

708 文档版本:20200417

Page 721: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

功能描述

ID² 运行时认证并加密接口

请求参数

名称 类型 是否必须 描述

apiVersioin String 是 api版本号,当前取值1.1.2

id2 String 是 ID²标识

authCode String 是 设备端生成的认证码

extra String 否 与认证码关联的辅助认证数据

data String 是 待加密的数据

productKey String 是 产品标识,从ID²控制台的产品列表中获取

返回值

成功: { "code":200, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": true, "data": "MIGfM****DAQAB" } 失败: { "code":33, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": false }

错误码

参见《错误码》

三、获取服务端随机数接口

接口名称

getServerRandom

访问地址

需要POP SDK支持,endpoint domain: id2.cn-shanghai.aliyuncs.com

文档版本:20200417 709

Page 722: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

功能描述

获取服务端随机数/挑战字

请求参数

名称 类型 是否必须 描述

apiVersioin String 是 api版本号,当前取值1.1.2

id2 String 是 ID²标识

返回值

成功: { "code" : 200, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": true, "data": "6F5DDB5F21C28F06484A4695FAB915AA" } 失败: { "code":18, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": false }

错误码

参见《错误码》

四、获取服务端认证码接口

接口名称

getServerAuthCodeAndEncryptData

访问地址

需要POP SDK支持,endpoint domain: id2.cn-shanghai.aliyuncs.com

功能描述

验证设备认证码有效性,获取服务端认证码,并加密数据

请求参数

名称 类型 是否必须 描述

id2 String 是 ID²标识

710 文档版本:20200417

Page 723: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

名称 类型 是否必须 描述

deviceAuthCode String 是 设备端生成的认证码,服务端通过其验证设备合法性

deviceExtra String 否 与设备认证码关联的辅助认证数据

data String 是 待加密的数据

deviceChallenge String 是 设备挑战字,用于生成服务端认证码

serverExtra String 否 与服务端认证码关联的辅助认证数据

apiVersion String 是 api版本号,当前取值1.1.2

productKey String 是 产品标识,从ID²控制台的产品列表中获取

返回值

成功: { "code": 200, "data": { "serverAuthCode": "10~2~3DDFA7A45590CF12~QaB/DeZhx4KpBahW***gAZ5Q==", "encryptData": "3s+wT***x4=" }, "success": true, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5" } 失败: { "code": 34, "data": null, "success": false, "requestId":"F6AFB45A-0FD1-405E-AD2A-C50E34C429E5" }

五、ID²空发接口

接口名称

otpGetId2

访问地址

需要POP SDK支持,endpoint domain: id2.cn-shanghai.aliyuncs.com

文档版本:20200417 711

Page 724: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

功能描述

ID²及其密钥的空发

请求参数

名称 类型 是否必须 描述

apiVersioin String 是 api版本号,当前取值1.1.2

deviceAuthCode String 是 设备认证码,基于空发token和设备端SDK生成。

返回值

成功: { "code": 200, "data": { "provisionData": "ATAww……nNfro=", //空发数据,设备从中解析出ID²和密钥 "remaining": 100 //空发授权余量 }, "success": true, "requestId": "F6AFB45A-0FD1-405E-AD2A-C50E34C429E5" } 失败: { "code": 34, "data": null, "requestId": "F6AFB45A-0FD1-405E-AD2A-C50E34C429E5", "success": false }

3.3.3 IROT硬件抽象层接口硬件初始化

函数原型: irot_result_t irot_hal_init(void);

功能描述: SE芯片初始化(例如打开SE芯片供电,初始化SE芯片会话等)

参数描述: void

返回值: 见irot_result_t

读取 ID2的 ID

函数原型:irot_result_t irot_hal_get_id2(uint8_t* id2, uint32_t* len);

功能描述:读取 ID2的 ID

712 文档版本:20200417

Page 725: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

参数描述:[OUT] id2,ID 的起始地址 [IN/OUT] len,输入为缓冲区长度,输出为 ID 的实际长

度。(HEX 数据格式, 当前长度为 12 字节)

返 回 值:见 irot_result_t

对称算法

函数原型:irot_result_t irot_hal_sym_crypto(key_object* key_obj, uint8_t key_id,

const uint8_t* iv, uint32_t iv_len,

const uint8_t* in, uint32_t in_len,

uint8_t* out, uint32_t* out_len,

sym_crypto_param_t* crypto_param );

功能描述:用对称算法实现数据的加解密

参数描述:[IN] key_obj, 密钥对象,见 key_object 类型

[IN] key_id, 密钥标识,索引内部密钥

[IN] iv,初始化向量地址

[IN] iv_len, 初始化向量长度

[IN] in,输入数据起始地址

[IN] in_len,输入数据长度

[OUT] out,,输出数据地址

[IN/OUT] out_len,输入为缓冲区大小,输出为真实数据长度

[IN] crypto_param,加解密参数结构,见 sym_crypto_param_t

备注:key_obj 和 key_id 两个参数为二选一使用,当 key_obj 参数不为 NULL,则使用此 参数作为

密钥进行运算。当 key_obj 参数为 NULL,则使用key_id 标识内部密钥进行运算。 其它类似 API 同

上。

非对称算法

私钥签名

函数原型:irot_result_t irot_hal_asym_priv_sign(key_object* key_obj, uint8_t key_id,

const uint8_t* in, uint32_t in_len,

uint8_t* out, uint32_t* out_len,

文档版本:20200417 713

Page 726: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

asym_sign_verify_t type);

功能描述:用私钥对数据进行签名

参数描述:[IN] key_obj, 密钥对象,见 key_object 类型

[IN] key_id, 密钥标识,索引内部密钥

[IN] in,待签名数据的起始地址

[IN] in_len,待签名数据的长度

[OUT] sign,签名数据的起始地址

[IN/OUT] sign_len,输入为缓冲区长度,输出为签名数据的实际长度

[IN] type,签名模式,见asym_sign_verify_t

返回值: 见irot_result_t

私钥解密

函数原型:irot_result_t irot_hal_asym_priv_decrypt(key_object* key_obj, uint8_t key_id,

const uint8_t* in, uint32_t in_len,

uint8_t* out, uint32_t* out_len,

asym_padding_t padding);

功能描述:用私钥对数据进行解密

参数描述:[IN] key_obj, 密钥对象,见 key_object 类型

[IN] key_id, 密钥标识,索引内部密钥

[IN] in,密文数据的起始地址

[IN] in_len,密文数据的长度

[OUT] out,明文数据的起始地址

[IN/OUT] out_len,输入为缓冲区长度,输出为明文数据的实际长度

[IN] padding,填充方式,见 asym_padding_t

返 回 值:见 irot_result_t

散列算法

函数原型:irot_result_t irot_hal_hash_sum(const uint8_t* in, uint32_t in_len,

714 文档版本:20200417

Page 727: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

uint8_t* out, uint32_t* out_len, digest_t type);

功能描述:用指定算法对数据做摘要

参数描述: [IN] in,原始数据的起始地址

[IN] in_len,原始数据的长度

[OUT] out,摘要数据的起始地址

[IN/OUT] out_len,输入为缓冲区长度,输出为摘要数据的实际长度

[IN] type,摘要算法,见 hash_t

返 回 值:见 irot_result_t

对称算法-块模式

typedef enum

{

BLOCK_MODE_ECB = 0x00,

BLOCK_MODE_CBC = 0x01,

BLOCK_MODE_CTR = 0x02,

} block_mode_t;

对称算法-填充类型

typedef enum

{

SYM_PADDING_NOPADDING = 0x00,

SYM_PADDING_PKCS5 = 0x02,

SYM_PADDING_PKCS7 = 0x03,

} irot_sym_padding_t;

非对称算法-填充类型

typedef enum

{

ASYM_PADDING_NOPADDING = 0x00,

文档版本:20200417 715

Page 728: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

ASYM_PADDING_PKCS1 = 0x01,

} irot_asym_padding_t;

加密解密类型

typedef enum

{

MODE_DECRYPT = 0x00,

MODE_ENCRYPT = 0x01,

} crypto_mode_t;

非对称算法-签名类型

typedef enum

{

ASYM_TYPE_RSA_MD5_PKCS1 = 0x00,

ASYM_TYPE_RSA_SHA1_PKCS1 = 0x01,

ASYM_TYPE_RSA_SHA256_PKCS1 = 0x02,

ASYM_TYPE_RSA_SHA384_PKCS1 = 0x03,

ASYM_TYPE_RSA_SHA512_PKCS1 = 0x04,

ASYM_TYPE_SM3_SM2 = 0x05,

ASYM_TYPE_ECDSA = 0x06,

} asym_sign_verify_t;

哈希算法类型

typedef enum

{

HASH_TYPE_SHA1 = 0x00,

HASH_TYPE_SHA224 = 0x01,

HASH_TYPE_SHA256 = 0x02,

HASH_TYPE_SHA384 = 0x03,

716 文档版本:20200417

Page 729: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

HASH_TYPE_SHA512 = 0x04,

HASH_TYPE_SM3 = 0x05,

} hash_t;

对称算法加解密参数

typedef struct _sym_crypto_param_t

{

cipher_t cipher_type; ///< cipher type

block_mode_t block_mode; ///< block mode

sym_padding_t padding_type; ///< padding type

mode_t mode; ///< mode(encrypt or decrypt)

} sym_crypto_param_t;

通用-密钥对象

typedef struct

{

struct

{

uint8_t key_object_type; ///< the key object type

} head;

struct

{

uint8_t buf[0x04]; ///< placeholder for key

} body;

} key_object;

对称算法-密钥对象

typedef struct

{

文档版本:20200417 717

Page 730: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

struct

{

uint8_t key_object_type;

} head;

struct

{

uint8_t* key_value; ///< the key value

uint32_t key_len; ///< the key length(bytes)

} body;

} key_object_sym;

RSA 公钥-密钥对象

typedef struct

{

struct

{

uint8_t key_object_type;

} head;

struct

{

uint8_t* e; ///< public exponent

uint32_t e_len; ///< public exponent length(bytes)

uint8_t* n; ///< public modulus

uint32_t n_len; ///< public modulus length(bytes)

} body;

} key_object_rsa_public;

718 文档版本:20200417

Page 731: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

RSA 私钥-密钥对象

typedef struct

{

struct

{

uint8_t key_object_type;

} head;

struct

{

uint8_t* d; ///< private exponent

uint32_t d_len; ///< private exponent length(bytes)

uint8_t* n; ///< private modulus

uint32_t n_len; ///< private modulus length(bytes)

} body;

} key_object_rsa_private;

RSA CRT 格式私钥-密钥对象

typedef struct

{

struct

{

uint8_t key_object_type;

} head;

struct

{

uint8_t* p; ///< 1st prime factor

uint8_t* q; ///< 2st prime factor

uint8_t* dp; ///< d % (p - 1)

文档版本:20200417 719

Page 732: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

uint8_t* dq; ///< d % (q - 1)

uint8_t* qinv; ///< (1/q) % p

uint32_t len; ///< the length for the 5 parameters must with the same length(bytes)

} body;

} key_object_rsa_crt_private;

附录

错误码定义

typedef enum

{

IROT_SUCCESS = 0, ///< The operation was successful.

IROT_ERROR_GENERIC = -1, ///< Non-specific cause.

IROT_ERROR_BAD_PARAMETERS = -2, ///< Input parameters were invalid.

IROT_ERROR_SHORT_BUFFER = -3, ///< The supplied buffer is too short for the output.

IROT_ERROR_EXCESS_DATA = -4, ///< Too much data for the requested operation was

passed.

IROT_ERROR_OUT_OF_MEMORY = -5, ///< System out of memory resources.

IROT_ERROR_COMMUNICATION = -7, ///< Communication error

IROT_ERROR_NOT_SUPPORTED = -8, ///< The request operation is valid but is not supported

in this implementation.

IROT_ERROR_NOT_IMPLEMENTED = -9, ///< The requested operation should exist but is not

yet implementation.

IROT_ERROR_TIMEOUT = -10,///< Communication Timeout

IROT_ERROR_ITEM_NOT_FOUND = -11,///< Id2 is not exist

} irot_result_t;

3.3.4 设备端SDK 适配手册此手册适用于:

• 硬件厂商、物联网开发者需要为某一款硬件/设备适配ID²。

720 文档版本:20200417

Page 733: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

• 设备使用了Android,Linux,AliOS Things系统。

• 使用了任一种安全载体:SE、SIM、KM、TEE。

一、OS适配接口:

基础功能:

1,void ls_osa_print(const char *fmt, …)

• 功能:打印函数,用于向串口或其他标准输出打印日志或调试信息。

• 参数:

名称 数据类型 描述

fmt const char * 格式化字符串

… void * 可变参数列表

2,int ls_osa_snprintf(char *str, size_t size, const char *fmt, ...)

• 功能:打印函数,向内存缓冲区格式化构建一个字符串。

• 参数:

名称 数据类型 描述

str char * 指向字符串缓冲的指针

size size_t 缓冲区的长度

fmt const char * 格式化字符串

… void * 可变参数列表

• 返回值:实际写入缓冲区的字符串长度。

3,void *ls_osa_malloc(size_t size)

• 功能:申请一块堆内存。

• 参数:

名称 数据类型 描述

size size_t 申请内存的字节大小

• 返回值:指向申请内存首地址的指针,失败返回NULL。

4,void *ls_osa_calloc(size_t nmemb, size_t size)

• 功能:分配nmemb个长度为size的连续堆内存,且内存数据置为0。

文档版本:20200417 721

Page 734: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

• 参数:

名称 数据类型 描述

nmemb size_t 内存块的数量

size size_t 单个内存的字节长度

• 返回值:指向申请内存首地址的指针,失败返回NULL。

5,void ls_osa_free(void *ptr)

• 功能: 释放参数ptr指向的一块堆内存。

• 参数:

名称 数据类型 描述

ptr void * 指向要释放的堆内存的地址

6,void ls_osa_msleep(unsigned int msec)

• 功能:睡眠函数,使当前执行线程睡眠指定的毫秒数。

• 参数:

名称 数据类型 描述

msec unsigned int 线程挂起的时间,单位毫秒

7,long long ls_osa_get_time_ms(void)

• 功能:获取当前系统的时间戳大小。

• 参数:void

• 返回值:系统的时间戳大小(以毫秒为单位)。

多线程:

1,int ls_osa_mutex_create(void **mutex)

• 功能: 创建一个互斥量,用于多线程下的同步访问。

• 参数:

名称 数据类型 描述

mutex void ** 指向创建互斥量的句柄

• 返回值:成功:= 0

失败:< 02,void ls_osa_mutex_destroy(void *mutex)

722 文档版本:20200417

Page 735: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

• 功能:销毁互斥量的句柄。

• 参数:

名称 数据类型 描述

mutex void * 互斥量的句柄

3,int ls_osa_mutex_lock(void *mutex)

• 功能:锁住一个互斥量。

• 参数:

名称 数据类型 描述

mutex void * 互斥量的句柄

• 返回值:

成功:= 0失败:< 0

4,int ls_osa_mutex_unlock(void *mutex)

• 功能:解锁一个互斥量。

• 参数:

名称 数据类型 描述

mutex void * 互斥量的句柄

• 返回值:

成功:= 0失败:< 0

网络操作:

1,int ls_osa_net_connect(const char *host, const char *port, int type)

• 功能:创建由host:port指定的特定类型的网络连接。

• 参数:

名称 数据类型 描述

host const char * 连接的主机地址

port const char* 连接的端口号

type int 网络类型,LS_NET_TYPE_XXX

• 返回值:

文档版本:20200417 723

Page 736: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

成功:网络连接的句柄失败:-12,void ls_osa_net_disconnect(int fd)

• 功能:断开网络连接,并释放相应资源。

• 参数:

名称 数据类型 描述

fd int 网络连接的句柄

3,int ls_osa_net_send(int fd, unsigned char *buf, size_t len, int *ret_orig)

• 功能:发送数据到指定的网络中。

• 参数:

名称 数据类型 描述

fd int 网络连接的句柄

buf unsigned char* 发送数据的内存

len size_t 发送数据的字节长度

ret_orig int * 接口返回失败时,指向具体的错误码

• 返回值:

成功:实际发送数据的长度失败:-14,int ls_osa_net_recv(int fd, unsigned char *buf, size_t

len, int timeout, int *ret_orig)

• 功能:在指定的时间内,从网络中读取最多len字节的数据。

• 参数:

名称 数据类型 描述

fd int 网络连接的句柄

buf unsigned char* 接收数据的内存

len size_t 内存的最大长度

timeout int 读取数据的时间值,0代码阻塞

ret_orig int * 接口返回失败时,指向具体的错误码

• 返回值:

成功:实际接收数据的长度失败:-1

724 文档版本:20200417

Page 737: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

二、HAL适配接口

Soft-KM:

1,int ls_hal_get_dev_id(uint8_t *dev_id, uint32_t *id_len)

• 功能:获取设备唯一ID。

• 参数:

名称 数据类型 描述

dev_id uint8_t * 存储设备唯一ID的内存

id_len uint32_t * 内存的长度(in),设备ID的实际长度(out)

• 返回值:

成功:= 0失败:-12,int ls_hal_open_rsvd_part(int flag)

• 功能:根据指定的权限(flag)打开预留的管理分区;如不支持文件系统,直接返回0。

• 参数:

名称 数据类型 描述

flag int 分区的读写权限

• 返回值:

成功:文件句柄失败:-13,int ls_hal_write_rsvd_part(int fd, uint32_t offset, void *data,

uint32_t data_len)

• 功能:向指定的分区中,写入data_len字节的数据。

• 参数:

名称 数据类型 描述

fd int 文件句柄;或者忽略(没有文件系统)

offset uint32_t 写数据的偏移量

data void * 写入的数据

data_len data_len 写入数据的长度(字节)

• 返回值:

文档版本:20200417 725

Page 738: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

成功:= 0失败:-14,int ls_hal_read_rsvd_part(int fd, uint32_t offset, void *buffer, uint32_t

read_len)

• 功能:从指定的分区中,读取read_len字节的数据。

• 参数:

名称 数据类型 描述

fd int 文件句柄;或者忽略(没有文件系统)

offset uint32_t 读数据的偏移量

buffer void * 读取数据的缓存

read_len data_len 读取数据的长度(字节)

• 返回值:

成功:= 0失败:-15,int ls_hal_close_rsvd_part(int fd)

• 功能:关闭打开的预留分区。

• 参数:

名称 数据类型 描述

fd int 文件句柄;或者忽略(没有文件系统)

• 返回值:

成功:= 0失败:-1

Secure Storage:

1,int ls_hal_kv_init(void)

• 功能:初始化安全存储模块。

• 参数:void

• 返回值:

成功:= 0失败:< 02,void ls_hal_kv_deinit(void)

• 功能:注销安全存储模块。

• 参数:void

3,int ls_hal_kv_set(const char *key, const void *value, int len, int sync)

• 功能:设置一组key-value到安全存储中。

726 文档版本:20200417

Page 739: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

• 参数:

名称 数据类型 描述

key const char * 存储数据的标识

value const void * 存储的数据

len int 存储数据的长度(字节)

sync int 同步/异步

• 返回值:

成功:= 0失败:< 04,int ls_hal_kv_get(const char *key, void *buffer, int *buffer_len)

• 功能:根据标识(key), 从安全存储中获取对应的数据。

• 参数:

名称 数据类型 描述

key const char * 存储数据的标识

buffer void * 存储数据的缓存

buffer_len int * 缓存长度/读取的数据长度

• 返回值:

成功:= 0失败:< 05,int ls_hal_kv_del(const char *key)

• 功能:删除安全存储中key标识的数据。

• 参数:

名称 数据类型 描述

key const char * 存储数据的标识

• 返回值:

成功:= 0失败:< 0

三、适配说明

OS适配:

在AliOS Things中,已经完成OS的适配;在第三方OS上,可根据应用/场景选择相应的OS接口适

配,其中基础功能(必须),多线程(多线程场景)和网络操作(使用iTLS安全连接)。

文档版本:20200417 727

Page 740: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

平台配置:

AliOS Things 2.1.0版本开始,Link Security SDK的配置统一提取到平台

的aos.mk中,如mk3080(board/mk3080/aos.mk):

其中:CONFIG_LS_DEBUG: 控制模块调试信息的开启和关闭。CONFIG_LS_ID2_OTP:控制ID2空

发的开启和关闭,其中SE不支持空发,配置无效。CONFIG_LS_KM_SE: 控制SE KM的开启和关

闭。CONFIG_LS_KM_TEE: 控制TEE KM的开启和关闭。

3.3.5 错误码

3.3.5.1 设备端错误代码错误码 错误含义

0 IROT_SUCCESS

-1 IROT_ERROR_GENERIC

-2 IROT_ERROR_BAD_PARAMETERS

-3 IROT_ERROR_SHORT_BUFFER

-4 IROT_ERROR_EXCESS_DATA

-5 IROT_ERROR_OUT_OF_MEMORY

-7 IROT_ERROR_COMMUNICATION

-8 IROT_ERROR_NOT_SUPPORTED

-9 IROT_ERROR_NOT_IMPLEMENTED

-10 IROT_ERROR_TIMEOUT

-11 IROT_ERROR_ITEM_NOT_FOUND

728 文档版本:20200417

Page 741: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3.3.5.2 iTLS错误码iTLS常见的错误警告类型

0 Peer close notify

10 Unexpected message

20 Bad record mac

50 Decode error

51 Decryption error

110 Unsupported extension

160 ID2 generic error

161 ID2 no quota

162 ID2 is not exist

163 ID2 authcode is invalid

164 ID2 has not been activated

165 The timestamp used in authcode is expired

166 ID2 challenge is invalid

167 Not support this operation

168 ID2 has been suspended

169 ID2 has been discarded

170 Permission denied, id2 has been blinded to other product key

171 Product key is invalid

172 Product key is not exist

173 ID2 server is busy

174 The device fingerprint is invalid

175 The device fingerprint is duplicated

176 ID2 server random is invalid

177 Hash type used in authcode generated is invalid

178 ID2 key type is invalid

文档版本:20200417 729

Page 742: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

3.3.5.3 服务端错误代码错误码 错误含义

200 成功

500 参数错误

700 系统错误

12 ID²已激活、已烧录

13 芯片不存在

14 签名验签、解密加密错误

15 烧录许可证不存在

16 配额不足

18 ID²不存在

21 认证码无效

32 ID²未激活

33 时间戳过期

34 时间戳认证码重复

35 挑战字无效

36 data无效

37 api版本无效

38 服务端认证码extra无效

39 设备端认证码extra无效

40 设备端挑战字无效

41 使用授权码无效

42 不支持该功能

43 ID²状态无效

44 ID²未完成烧录

45 ID²已暂停使用

46 ID²已废弃

47 用户无权操作

48 厂商编码无效

49 产品编码无效

50 ID²已过期

730 文档版本:20200417

Page 743: 阿里云IoT Link Rack 一体机

开发指南 /  3 物联网设备身份认证

错误码 错误含义

51 产品不存在

52 厂商未注册

53 ID²下载数量受限

54 系统繁忙

55 空发未使能

56 无效指纹

57 重复的设备指纹

文档版本:20200417 731

Page 744: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4 物联网络管理平台

4.1 云端开发指南

4.1.1 云端API参考

4.1.1.1 API列表以下是物联网络管理平台 API 列表。

基础管理

API 描述

GetUserLicense 获取用户合约信息

ListFreqBandPlanGroups 获取频谱计划组支持列表

GetFreqBandPlanGroup 获取频谱计划组信息

ListActivatedFeatures 获取用户可使用功能列表

网关管理相关API

API 描述

GetGateway 新增网关

DeleteGateway 删除网关

UpdateGateway 更新网关信息

UpdateGatewayEnablingState 更新网关启用状态

GetGateway 获取网关信息

ListGateways 获取网关信息列表

CountGateways 获取符合条件的网关数量

ListActivatedFeatures 获取所有网关的地理位置信息

网络管理相关API

API 描述

CreateLocalJoinPermission 创建专用入网凭证

DeleteLocalJoinPermission 删除专用入网凭证

732 文档版本:20200417

Page 745: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

API 描述

UpdateOwnedLocalJoinPermission 更新专用入网凭证的信息

UpdateOwnedLocalJoinPermissionEnablingState更新专用入网凭证的启停状态

GetOwnedJoinPermission 获取入网凭证基本信息

ListOwnedJoinPermissions 获取符合条件的入网凭证列表

CountOwnedJoinPermissions 获取符合条件的入网凭证数量

GetRentedJoinPermission 获取租用入网凭证的基本信息

ListRentedJoinPermissions 获取符合条件的租用入网凭证列表

CountRentedJoinPermissions 获取符合条件的租用入网凭证数量

ReturnJoinPermission 退租入网凭证

SubmitJoinPermissionAuthOrder 发起入网凭证授权流程

CancelJoinPermissionAuthOrder 取消入网凭证授权流程

AcceptJoinPermissionAuthOrder 同意入网凭证授予

RejectJoinPermissionAuthOrder 拒绝入网凭证授予

GetJoinPermissionAuthOrder 获取入网凭证授权详情

节点管理相关API

API 描述

CreateNodeGroup 创建节点分组

DeleteNodeGroup 删除节点分组。

UpdateNodeGroup 更新节点分组的信息

GetNodeGroup 获取节点分组详情

ListNodeGroups 获取符合条件的节点分组列表

CountNodeGroups 获取符合条件的节点分组数量

BindJoinPermissionToNodeGroup 分配入网凭证于节点分组

UnbindJoinPermissionFromNodeGroup 取消入网凭证于节点分组

UpdateDataDispatchConfig 更新数据流转配置

UpdateDataDispatchEnablingState 更新数据流转出口的启停用

AddNodeToGroup 增加节点到节点分组

RemoveNodeFromGroup 删除节点分组中的节点

GetNode 获取节点信息

文档版本:20200417 733

Page 746: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

API 描述

ListNodesByOwnedJoinPermissionId 获取专用凭证下的节点列表

ListNodesByNodeGroupId 获取节点分组下的节点列表

CountNodesByOwnedJoinPermissionId 获取符合凭证条件的节点数量

CountNodesByNodeGroupId 获取符合分组条件的节点数量

上下行数据相关API

API 描述

SendUnicastCommand 发送下行数据

密钥管理API

API 描述

CountGatewayTupleOrders 获取已提交网关安全密钥工单数量

CountNodeTupleOrders 获取已提交节点安全元组工单数量

GetGatewayTupleOrder 获取网关安全元组工单信息

GetGatewayTuplesDownloadUrl 获取颁发给用户的网关安全元组

GetNodeTupleOrder 获取节点安全元组工单信息

GetNodeTuplesDownloadUrl 获取颁发给用户的节点安全元组

ListGatewayTupleOrders 获取用户已提交的网关元组工单列表

ListNodeTupleOrders 获取用户已提交的节点元组工单列表

SubmitNodeTupleOrder 提交节点密钥申请工单

SubmitGatewayTupleOrder 提交网关密钥申请工单

4.1.1.2 概述通过向 API 的服务端地址发送HTTPS/HTTP GET/POST请求,并按照API接口说明,在请求中加入相

应请求参数来调用 API 接口。根据请求的处理情况,系统会返回处理结果。

我们将从以下两个方面介绍API的调用方法。

• 调用API

• 公共参数

734 文档版本:20200417

Page 747: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.3 公共参数本文档列举了物联网络管理平台 API 的公共请求参数和公共返回参数。

公共请求参数是调用每个 API 时都需要使用的请求参数。

名称 类型 是否必需 描述

Format String 是 返回值的类型,支持 JSON 和 XML 类型。

Version String 是 API版本号,为日期形式:YYYY-MM-DD,最新版本为2019-03-01。每个接口可以存在多个版本。

AccessKeyId String 是 阿里云颁发给用户的访问服务所用的密钥 Id。

Signature String 是 签名结果串。

SignatureMethod String 是 签名方式,目前支持 HMAC-SHA1。

Timestamp String 是 请求的时间戳。日期格式按照 ISO8601标准表示,并需要使用 UTC 时间。格式为YYYY-MM-DDThh:mm:ssZ。例如:2019-01-20T12:00:00Z(为北京时间2019年01月20日20点0分0秒)。

SignatureVersion String 是 签名算法版本。目前版本是1.0。

SignatureNonce String 是 唯一随机数。用于防止网络重放攻击。用户在不同请求中要使用不同的随机数值。

RegionId String 是 服务所在地域(与控制台上的Region对应),目前仅支持 cn-shanghai。

Action String 是 API 方法名,用来指定所请求的操作。

文档版本:20200417 735

Page 748: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

示例

https://linkwan.cn-shanghai.aliyuncs.com/?Format=JSON&Version=2019-01-20&Signature=Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D&SignatureMethod=HMAC-SHA1&SignatureNonce=15215528852396&SignatureVersion=1.0&AccessKeyId=...&Timestamp=2019-01-20T12:00:00Z&RegionId=cn-shanghai&Action=GetGateway&GwEui=0000000000000000

公共返回参数

API 返回结果采用统一格式。返回 4xx 或 5xx HTTP 状态码代表未能成功调用到物联网络管理平台的

服务(例如签名错误等情况)。返回 2xx HTTP 状态码代表成功调用到物联网络管理平台的服务,但

API 请求的成功与否取决于具体的返回内容。返回的数据格式有 JSON 和 XML 两种,可以在发送请求

时指定返回的数据格式。

每次请求接口,无论成功与否,系统都会返回本次请求的唯一标识 RequestId。

API 调用返回 2xx HTTP 状态码的情况下,存在请求成功、请求失败两类情况。下文例举这两类情况

的返回内容。

请求成功示例

• JSON 格式

{ "RequestId": "89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success": true, "Data": "返回的业务数据,Data 字段可能是列表、字典或简单类型。此外,并非所有 API 方法的返回参数中都包含 Data 字段。"}

• XML 格式

<?xml version="1.0" encoding="utf-8"?><API 方法名 + Response> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success> <Data>返回的业务数据,Data 字段可能是列表、字典或简单类型。此外,并非所有 API 方法的返回参数中都包含 Data 字段。</Data></API 方法名 + Response>

请求失败示例

• JSON 格式

{ "RequestId": "89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Code": "InternalError",

736 文档版本:20200417

Page 749: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

"Message": "The request processing has failed due to some unknown error, exception or failure."}

• XML 格式

<?xml version="1.0" encoding="utf-8"?><API 方法名 + Response> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Code>InternalError</Code> <Message>The request processing has failed due to some unknown error, exception or failure.</Message></API 方法名 + Response>

4.1.1.4 调用API您可以通过发起HTTP请求调用物联网络管理平台 API。

请求结构如下:

https://[Endpoint]/?Action=Xxx&[Parameters]

其中:

• Endpoint - 调用的云服务的接入地址。物联网络管理平台的接入地址分别如下。

应用网关IP:port/data/api.json

说明:

具体应用网关IP:port由项目交付时确定。

• Action - API 方法名,即要执行的操作。例如查询网关信息的方法名为GetGateway。

• Parameters - 请求参数。每个参数之间用(&)分隔。

请求参数由公共请求参数和 API 自定义参数组成。公共参数中包含 API 版本号、身份验证等信

息。

下面以调用名为GetGateway的API方法为例,说明请求串的格式。

https://POP网关域名?Format=JSON&Version=2019-01-20&Signature=Pc5WB8gokVn0xfeu%2FZV%2BiNM1dgI%3D&SignatureMethod=HMAC-SHA1&SignatureNonce=15215528852396&SignatureVersion=1.0&AccessKeyId=...&Timestamp=2019-01-20T12:00:00Z&RegionId=cn-shanghai&Action=GetGateway&GwEui=0000000000000000

文档版本:20200417 737

Page 750: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.5 错误码本文分类型列举调用物联网络管理平台 API 出错时,返回的错误码。其中公共错误码为所有 API 方法

都有可能返回的错误。

以下表格中的某些行包含一个以上错误码,其中最后一个为粗体。粗体的错误码在目前公测版的平台

不存在,但今后会取代非粗体的错误码。对于云端开发者而言,建议的合理做法是同时处理这些错误

码。

错误码 描述

MissingParameter 缺少必要的参数。

InvalidName, IllegalName 名称不合法(部分 API 方法需要调用者传入某些“名称”字段,若这些名称字段不合法,则会返回此码)。

InvalidParameter, IllegalParameter 存在非法参数。

NotResourceOwner, NonExistent,Nonexistent

操作的资源不存在,或当前账号不是所要操作的资源的拥有者。

Abandoned 调用的 API 方法已经下架,不再支持。

InternalError 物联网络管理平台内部错误或异常。

CloudProductNotActivated,UnqualifiedAccount

当前账号没有开通物联网络管理平台服务。

FeatureNotActivated, UnactivatedFeature 用户账号没有开通当前操作所涉及的平台功能。

ResourceLocked, LockedResource 操作的资源被某种特殊机制锁定,操作无法进行。

InvalidFreqBandPlan,InvalidFrequencyBandPlan

参数中出现了无效的频段(频段 Id)。

网关管理错误码

错误码 描述

GwEuiDuplicated, DuplicatedGwEui 相同 GwEUI 的网关已经存在。

GatewayTupleAlreadyAbandoned,IotHubTripleMissing, InvalidGwEui

无效的 GwEUI。

InvalidPinCode 网关 PIN Code 验证失败。

TooManyPinCodeVerificationFailures,FrequentInvalidPinCode

由于 PIN Code 验证失败的频率过高,导致当前操作失败。

GatewayAlreadyBoundToOthers,OwnedByOther

该网关已经被其他阿里云用户录入。

738 文档版本:20200417

Page 751: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

错误码 描述

ExceedGatewayLimit,ReachedGatewayLimit

录入的网关数量已经到达接入上限。

入网凭证管理错误码

错误码 描述

JoinPermissionNameDuplicated,DuplicatedJoinPermissionName

创建专用入网凭证时,使用的凭证名称与现有的凭证重复,创建失败。

ExceedLocalJoinPermissionLimit,ReachedLocalJoinPermissionLimit

创建的专用入网凭证数量已经到达上限。

JoinPermissionAlreadyAuthorized,AuthorizedJoinPermission

由于当前操作涉及的专用入网凭证已经授权给某个租户,导致操作失败。

JoinPermissionAlreadyBoundNodeGroup,EngagedJoinPermission

由于操作的入网凭证已经与某个节点分组建立了关联,导致当前操作失败。

入网凭证授权、受权、申请相关错误码

错误码 描述

JoinPermissionNameDuplicated,DuplicatedJoinPermissionName

申请泛在入网凭证时,使用的凭证名称与现有的凭证重复,申请失败。

ExceedRoamingJoinPermissionLimit,ReachedRoamingJoinPermissionLimit

申请的泛在入网凭证数量已经到达上限。

JoinPermissionAlreadyBoundNodeGroup,EngagedJoinPermission

由于操作的入网凭证已经与某个节点分组建立了关联,导致当前操作失败。

JoinPermissionAlreadyAuthorized,AuthorizedJoinPermission

由于入网凭证已经被授权,导致当前操作失败。

RenterDoesNotExist,InvalidJoinPermissionRenter

由于当前操作涉及的入网凭证租户账号无效,导致操作失败。

TooManyRenterNonExistentFailures,FrequentInvalidJoinPermissionRenter

因为过于频繁的触发“凭证租户账号无效”错误,导致当前操作被拒绝,请过一段时间再尝试。

IllegalOrderStateTransition 非法的入网凭证授权工单状态迁移。

节点分组管理错误码

错误码 描述

NodeGroupNameDuplicated,DuplicatedNodeGroupName

节点分组名称已经存在。

文档版本:20200417 739

Page 752: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

错误码 描述

ExceedNodeLimit, ReachedNodeLimit 由于录入的节点数量已经到达当前用户的服务上限,导致操作失败。

NodeGroupDoesNotExist,NonexistentNodeGroup

操作涉及的节点分组不存在。

NodeGroupAlreadyBoundJoinPermission,PermittedToJoinAlready

由于当前操作涉及的节点分组已经与某个入网凭证建立了关联,导致操作失败。

JoinPermissionDoesNotExist,NonexistentJoinPermission

由于当前操作涉及的入网凭证不存在,导致操作失败。

JoinPermissionAlreadyBoundNodeGroup,EngagedJoinPermission

由于当前操作涉及的入网凭证已经与某个节点分组建立了关联,导致操作失败。

NodeDoesNotExist, InvalidDevEui 无效的 DevEUI。

DevEuiDuplicated, ExistentNode 当前分组已经包含了目标节点。

NodeAlreadyAdded, DuplicatedDevEui 相同 DevEUI 的节点已经存在于其他分组。

OwnedByOther 该节点已经被其他阿里云用户录入。

InvalidPinCode 节点 PIN Code 验证失败。

TooManyPinCodeVerificationFailures,FrequentInvalidPinCode

由于 PIN Code 验证失败的频率过高,导致当前操作失败。

组播管理错误码

错误码 描述

MulticastAddressAssignmentFailed 组播地址分配失败。

MulticastKeyGenerationFailed 组播密钥生成失败。

MulticastGroupBoundNodesIsNotEmpty,NonemptyMulticastGroup

由于当前操作涉及的组中存在节点,导致操作失败。

ExceedMaxMulticastNodesBoundCount,ReachedMulticastGroupCapacity

组中的节点数量达到组容量上限。

实验室网关管理错误码

错误码 描述

ExceedLabGatewayLimit,ReachedLabGatewayLimit

由于使用的实验室网关数量已经到达上限,当前操作失败。

BoundLabNodesIsNotEmpty,AssociatedWithNodes

由于当前操作涉及的实验室网关绑定了一些实验节点,导致操作失败。

740 文档版本:20200417

Page 753: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

实验室节点管理错误码

错误码 描述

ExceedLabNodeLimit,ReachedLabNodeLimit

由于使用的实验室节点数量已经到达上限,当前操作失败。

LabGatewayDoesNotExist,NonexistentLabGateway

由于当前操作涉及的实验网关不存在,导致操作失败。

网关安全元组错误码

错误码 描述

ExceedGatewayTupleLimit,ReachedGatewayTupleLimit

申请的网关安全元组数量已经到达上限。

节点安全元组错误码

错误码 描述

ExceedNodeTupleLimit,ReachedNodeTupleLimit

由于申请的节点安全元组数量已经到达上限,导致当前操作失败。

ExceedMaxNodeTuplesRequiredCount,ReachedMaximumTuplesForRequest

请求的节点安全元组数量超过单次请求的上限。

IllegalStateTransition,IllegalOrderStateTransition

非法的节点安全元组工单状态迁移。

KpmPublicKeyUnregistered,MissingProductLineKey

安全产线服务的公钥未注册。

KpmKeysGenerationFailed,ProductLineServiceError

安全产线服务在生成安全元组时发生错误。

KpmOrderNotReady,KpmNodeTupleOrderNotReady,PendingTupleOrder

由于当前操作涉及的安全产线工单尚在处理中,导致操作失败。

4.1.1.6 基础管理

文档版本:20200417 741

Page 754: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.6.1 ListActivatedFeatures列举当前用户账号在物联网络管理平台所能使用的功能。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListActivatedFeatures

系统规定参数。取值:ListActiva

tedFeatures。

返回数据

名称 类型 示例值 描述

Data GATEWAY_TUPLE 当前用户账号在物联网络管理平台所能使

用的功能的列表。

参考Feature 枚举定义

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListActivatedFeatures&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data>GATEWAY</Data><Data>JOIN_PERMISSION_AUTHORIZATION</Data><Data>LOCAL_JOIN_PERMISSION</Data><Data>ROAMING_JOIN_PERMISSION</Data><Data>LAB_NODE</Data><Data>LAB_GATEWAY</Data><Data>GATEWAY_TUPLE</Data><Data>NODE_TUPLE</Data><Data>NOTIFICATION</Data><Data>KPM_PRODUCT_LINE</Data><Data>NODE</Data><Data>UNICAST</Data>

742 文档版本:20200417

Page 755: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<Data>MULTICAST</Data>

JSON 格式

{ "Data":[ "GATEWAY", "JOIN_PERMISSION_AUTHORIZATION", "LOCAL_JOIN_PERMISSION", "ROAMING_JOIN_PERMISSION", "LAB_NODE", "LAB_GATEWAY", "GATEWAY_TUPLE", "NODE_TUPLE", "NOTIFICATION", "KPM_PRODUCT_LINE", "NODE", "UNICAST", "MULTICAST" ], "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

类型说明

Feature 枚举定义

名称 类型 描述

GATEWAY_TUPLE String 网关安全元组申请、下载等能

力。一般而言,网关生产商类的

用户需要此类功能。

NODE_TUPLE String 节点安全元组申请、下载等能

力。一般而言,模组、设备生产

商类的用户需要此类功能。

NODE String 节点管理能力。开发者(解决方

案供应商)需要此类功能。

GATEWAY String 网关管理能力。网络运营者需要

此类功能。

LOCAL_JOIN_PERMISSION String 本地入网凭证的创建、编辑、销

毁等能力。网络运营者需要此类

功能。

文档版本:20200417 743

Page 756: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 描述

ROAMING_JOIN_PERMISSION String 泛在入网凭证的申请、编辑、销

毁等能力。开发者(解决方案供

应商)需要此类功能。

JOIN_PERMISSION_AUTH

ORIZATION

String 凭证权限授受能力。网络运营者

与开发者(解决方案供应商)都

可能需要此类功能。

LAB_NODE String 实验室节点管理能力。一般而

言,模组、设备生产商类的用户

可能需要此类功能。

LAB_GATEWAY String 实验室网关管理能力。一般而

言,网关生产商类的用户可能需

要此类功能。

NOTIFICATION String 消息系统能力,包括查收、处理

告警消息及授权消息等的能力。

网络运营者与开发者(解决方案

供应商)都需要此类功能。

KPM_PRODUCT_LINE String 安全产线能力。此功能需要配合

产线 SDK 使用。

UNICAST String 向 LoRaWAN 节点下发数据包

的能力。开发者(解决方案供应

商)需要此类功能。

MULTICAST String 下发 LoRaWAN 组播消息及管

理组播群组的能力。开发者(解

决方案供应商)可能需要此类功

能。

744 文档版本:20200417

Page 757: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

访问错误码查看更多错误码。

4.1.1.6.2 GetFreqBandPlanGroup调用GetFreqBandPlanGroup获取频段信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetFreqBandPlanGroup

系统规定参数。取值:GetFreqBan

dPlanGroup。

GroupId Long 是 201 频段ID。

返回数据

名称 类型 示例值 描述

Data - - 频段信息。

BeginFrequency

Long 923 起始频点,单位为MHz。

EndFrequency Long 925 结束频点,单位为MHz。

FrequencyRegionId

String CN Region标识。

文档版本:20200417 745

Page 758: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

FrequencyType

String SAME_FREQUENCY 频段类型。取值范围:

• SAME_FREQUENCY:同频• DIFF_FREQUENCY:异频

GroupId Long 201 频段ID。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetFreqBandPlanGroup&GroupId=201&<公共请求参数>

正常返回示例

XML 格式

<GetFreqBandPlanGroupResponse> <Data> <BeginFrequency>923</BeginFrequency> <EndFrequency>925</EndFrequency> <FrequencyRegionId>CN</FrequencyRegionId> <GroupId>201</GroupId> <FrequencyType>SAME_FREQUENCY</FrequencyType> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetFreqBandPlanGroupResponse>

JSON 格式

{ "Data":{ "FrequencyRegionId":"CN", "FrequencyType":"SAME_FREQUENCY", "BeginFrequency":923, "GroupId":201, "EndFrequency":925 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

746 文档版本:20200417

Page 759: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.6.3 GetUserLicense调用GetUserLicense查询当前用户账号在物联网络管理平台的合约信息及合约执行情况。这里

的“合约”与“执行情况”主要指各项服务的容量与当前使用量。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetUserLicense 系统规定参数。取值:GetUserLic

ense。

返回数据

名称 类型 示例值 描述

Data - - 各项服务的容量与当前使用量。

GatewayCount

Long 100 网关接入服务的用量。

表示当前用户账号已经接入的网关数量。

GatewayFreeLimit

Long 100 网关接入服务的免费容量。

表示当前用户账号可以免费接入的网关数

量上限,其值必然小于等于 GatewayLim

it。

文档版本:20200417 747

Page 760: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

GatewayLimit Long 100 网关接入服务的容量。

表示当前用户账号可以接入的网关数量上

限。

GatewayPrePayCount

Long 100 网关接入服务的预付费数量。

表示当前用户账号已经接入的预付费网关

数量。

GatewayTupleCount

Long 100 网关安全元组的服务用量。

表示当前用户账号已经申请了的网关安全

元组的数量。

GatewayTupleFreeLimit

Long 100 网关安全元组的免费服务容量。

表示当前用户账号可以申请的免费网关

安全元组的数量,其值必然小于等于

GatewayTupleLimit。

GatewayTupleHybridCount

Long 100 hybird网关秘钥已用数量。

表示当前用户账号已经使用的hybird网关

秘钥数量。

GatewayTupleHybridLimit

Long 100 hybird网关秘钥容量。

表示当前用户账号可以使用的hybird网关

秘钥数量上限。

GatewayTupleLimit

Long 100 网关安全元组的服务容量。

表示当前用户账号最多可以申请的网关安

全元组的数量。

GatewayTupleSingleChannelCount

Long 100 单通道网关已用数量。

表示当前用户账号接入服务的单通道网关

数量。

748 文档版本:20200417

Page 761: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

GatewayTupleSingleChannelLimit

Long 100 网关单通道密钥配额。

表示当前用户账号网关单通道密钥配额。

GatewayTupleStandardCount

Long 100 网关合约秘钥-标准规格已用数量。

表示当前用户账号已用的网关合约秘钥-标

准规格数量。

GatewayTupleStandardLimit

Long 100 网关合约秘钥-标准规格限额。

表示当前用户账号可以接入网关合约秘

钥-标准规格容量。

LocalJoinPermissionCount

Long 100 专用入网凭证服务的用量。

针对网络运营者类的用户,表示当前用户

账号已经创建的专用入网凭证的数量。

LocalJoinPermissionFreeLimit

Long 100 专用入网凭证服务的免费容量。

针对网络运营者类的用户,表示当前用

户账号可以免费创建的专用入网凭证的

数量上限,其值必然小于等于LocalJoinP

ermissionLimit。

LocalJoinPermissionLimit

Long 100 专用入网凭证服务的容量。

针对网络运营者类的用户,表示当前用户

账号可以创建的专用入网凭证的数量上

限。

NodeCount Long 100 节点接入服务的用量。

表示当前用户账号已经接入的节点数量。

NodeFreeLimit

Long 100 节点接入服务的免费容量。

表示当前用户账号可以免费接入的节点数

量上限,其值必然小于等于NodeLimit。

文档版本:20200417 749

Page 762: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

NodeLimit Long 100 节点接入服务的容量。

表示当前用户账号可以接入的节点数量上

限。

NodeTupleCount

Long 100 节点安全元组的服务用量。

表示当前用户账号已经申请了的节点安全

元组的数量。

NodeTupleFreeLimit

Long 100 节点安全元组的免费服务容量。

表示当前用户账号可以申请的免费节点

安全元组的数量,其值必然小于等于

NodeTupleLimit。

NodeTupleLimit

Long 100 节点(LoRaWAN模组)安全元组的服务

容量。

表示当前用户账号最多可以申请的节点安

全元组的数量。

NodeTupleRelayCount

Long 100 中继密钥已用数量。

表示当前用户账号接入的中继密钥数量。

NodeTupleRelayLimit

Long 100 中继密钥配额。

表示当前用户账号中继密钥配额。

NodeTupleStandardCount

Long 100 节点合约秘钥-标准规格已用数量。

表示当前用户账号已用节点合约秘钥-标准

规格数量。

NodeTupleStandardLimit

Long 100 节点合约秘钥-标准规格限额。

表示当前用户账号可以接入节点合约秘

钥-标准规格容量。

750 文档版本:20200417

Page 763: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

Oui String 0000 LoRaWAN模组、设备制造商类的用户的

组织码。改组织码会体现在用户申请到的

DevEUI中。

RelayCount Long 100 中继节点已用数量。

表示当前用户已用中级节点数量。

RelayLimit Long 100 中继节点配额。

表示当前用户账号中继节点配额。

RoamingJoinPermissionCount

Long 100 泛在入网凭证服务的用量。

针对开发者类的用户,表示当前用户账号

已经申请的泛在入网凭证的数量。

RoamingJoinPermissionFreeLimit

Long 100 泛在入网凭证服务的免费容量。

针对开发者类的用户,表示当前用户账

号可以免费申请的泛在入网凭证的数量

上限,其值必然小于等于RoamingJoi

nPermissionLimit。

RoamingJoinPermissionLimit

Long 100 泛在入网凭证服务的容量。

针对开发者(解决方案供应商)类的用

户,表示当前用户账号可以申请的泛在入

网凭证的数量上限。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetUserLicense

文档版本:20200417 751

Page 764: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&<公共请求参数>

正常返回示例

XML 格式

<GetUserLicenseResponse> <Data> <LabGatewayLimit>100</LabGatewayLimit> <Oui>0000</Oui> <GatewayLimit>100</GatewayLimit> <NodeTupleCount>100</NodeTupleCount> <RoamingJoinPermissionCount>100</RoamingJoinPermissionCount> <LocalJoinPermissionCount>100</LocalJoinPermissionCount> <GatewayTupleCount>100</GatewayTupleCount> <NodeTupleLimit>100</NodeTupleLimit> <LocalJoinPermissionLimit>100</LocalJoinPermissionLimit> <NodeCount>100</NodeCount> <RoamingJoinPermissionLimit>100</RoamingJoinPermissionLimit> <GatewayCount>100</GatewayCount> <LabNodeCount>100</LabNodeCount> <GatewayTupleLimit>100</GatewayTupleLimit> <LabNodeLimit>100</LabNodeLimit> <NodeLimit>100</NodeLimit> <LabGatewayCount>100</LabGatewayCount> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetUserLicenseResponse>

JSON 格式

{ "Data":{ "LabNodeLimit":100, "GatewayTupleCount":100, "RoamingJoinPermissionCount":100, "LabNodeCount":100, "GatewayTupleLimit":100, "LocalJoinPermissionCount":100, "GatewayCount":100, "Oui":"0000", "LocalJoinPermissionLimit":100, "LabGatewayLimit":100, "RoamingJoinPermissionLimit":100, "NodeCount":100, "NodeTupleCount":100, "LabGatewayCount":100, "NodeTupleLimit":100, "GatewayLimit":100, "NodeLimit":100 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

752 文档版本:20200417

Page 765: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.6.4 ListFreqBandPlanGroups调用ListFreqBandPlanGroups获取频段列表。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListFreqBandPlanGroups

系统规定参数。取值:ListFreqBa

ndPlanGroups。

返回数据

名称 类型 示例值 描述

Data - - 频段列表。

BeginFrequency

Long 470 起始频点,单位为MHz。

EndFrequency Long 510 结束频点,单位为MHz。

FrequencyRegionId

String CN Region标识。

FrequencyType

String SAME_FREQUENCY 频段类型。取值范围:

• SAME_FREQUENCY:同频• DIFF_FREQUENCY:异频

GroupId Long 101 频段ID。

文档版本:20200417 753

Page 766: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListFreqBandPlanGroups&<公共请求参数>

正常返回示例

XML 格式

<ListFreqBandPlanGroupsResponse> <Data> <FreqBandPlanGroup> <BeginFrequency>470</BeginFrequency> <EndFrequency>510</EndFrequency> <FrequencyRegionId>CN</FrequencyRegionId> <GroupId>101</GroupId> <FrequencyType>SAME_FREQUENCY</FrequencyType> </FreqBandPlanGroup> <FreqBandPlanGroup> <BeginFrequency>470</BeginFrequency> <EndFrequency>510</EndFrequency> <FrequencyRegionId>CN</FrequencyRegionId> <GroupId>102</GroupId> <FrequencyType>DIFF_FREQUENCY</FrequencyType> </FreqBandPlanGroup> <FreqBandPlanGroup> <BeginFrequency>923</BeginFrequency> <EndFrequency>925</EndFrequency> <FrequencyRegionId>CN</FrequencyRegionId> <GroupId>201</GroupId> <FrequencyType>SAME_FREQUENCY</FrequencyType> </FreqBandPlanGroup> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ListFreqBandPlanGroupsResponse>

JSON 格式

{ "Data":[ { "FrequencyRegionId":"CN", "FrequencyType":"SAME_FREQUENCY", "BeginFrequency":470, "GroupId":101, "EndFrequency":510

754 文档版本:20200417

Page 767: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}, { "FrequencyRegionId":"CN", "FrequencyType":"DIFF_FREQUENCY", "BeginFrequency":470, "GroupId":102, "EndFrequency":510 }, { "FrequencyRegionId":"CN", "FrequencyType":"SAME_FREQUENCY", "BeginFrequency":923, "GroupId":201, "EndFrequency":925 } ], "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.7 网关管理

4.1.1.7.1 CountGateways调用CountGateways统计当前用户账号名下符合过滤条件的网关数量。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountGateways 系统规定参数。取值:CountGatew

ays。

FreqBandPlanGroupId

Long 否 123 网关频段ID过滤。

FuzzyCity String 否 杭州 城市名模糊过滤。

FuzzyGwEui String 否 123456 GwEUI模糊过滤。

文档版本:20200417 755

Page 768: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

FuzzyName String 否 name 网关名称模糊过滤。

IsEnabled Boolean 否 false 网关启停用状态过滤。

若未传入此参数,则不限制启停状

态。

OnlineState String 否 ONLINE 网关在离线状态过滤。

若未传入此参数,则不限制在线状

态。可取值为ONLINE和OFFLINE。

返回数据

名称 类型 示例值 描述

Data Long 100 满足过滤条件的网关总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CountGateways&<公共请求参数>

正常返回示例

XML 格式

<CountGatewaysResponse> <Data>100</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CountGatewaysResponse>

JSON 格式

{ "Data":100, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

756 文档版本:20200417

Page 769: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.7.2 CreateGateway调用CreateGateway录入网关。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CreateGateway 系统规定参数。取值:CreateGate

way。

Address String 是 详细地址 网关所在详细地址。

AddressCode Long 是 123 网关所在地区ID, 由http://lbs.

amap.com/api/javascript-api/

download定义。

City String 是 杭州 网关所在城市名称。

CommunicationMode

String 是 HALF_DUPLEX 网关通信模式。取值:

FULL_DUPLEX(全双工)|

HALF_DUPLEX(半双工)。

District String 是 滨江区 网关所在城区名称。

FreqBandPlanGroupId

Long 是 123 网关频段ID。

GisCoordinateSystem

String 是 GCJ_02 网关经纬度所采用的坐标系统,可取

值为WGS_84, GCJ_02。

文档版本:20200417 757

Page 770: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

GwEui String 是 0000000000000000

网关唯一标识。

Latitude Float 是 23.45678 网关纬度。

Longitude Float 是 123.45678 网关经度。

Name String 是 vme 自定义网关名称。

PinCode String 是 000000 网关PinCode, 用于确保录入者拥有

该网关。

Description String 否 my gateway 自定义网关描述信息。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CreateGateway&Address=详细地址&AddressCode=123&City=杭州&CommunicationMode=HALF_DUPLEX&District=滨江区&FreqBandPlanGroupId=123&GisCoordinateSystem=GCJ_02&GwEui=0000000000000000&Latitude=23.45678&Longitude=123.45678&Name=vme&PinCode=000000&<公共请求参数>

正常返回示例

XML 格式

<CreateGatewayResponse>

758 文档版本:20200417

Page 771: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CreateGatewayResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 GwEuiDuplicated A gateway with the same gwEui already exists.

GwEUI 已存在

400 GatewayTupleAlreadyAbandoned

The specified gateway tuple has been abandoned.

网关元组已经废弃

400 IotHubTripleMissing

The IoT Platform trituple of this gateway does not exist.

找不到网关的物联网套件三元组

400 InvalidPinCode An error occurred while verifying PinCode.

PinCode校验失败

400 GatewayAlreadyBoundToOthers

This gateway has already been bound to another account.

网关已经绑定到其它账号

400 ExceedGatewayLimit

The maximum number of gateways is exceeded.

超出网关可使用额度

400 InvalidFreqBandPlan

The frequency band plan is invalid.

频段计划不可用

400 InvalidName The specified name is invalid.

名称不合法

文档版本:20200417 759

Page 772: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.7.3 DeleteGateway调用DeleteGateway删除已录入的网关。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 DeleteGateway 系统规定参数。取值:DeleteGate

way。

GwEui String 是 0000000000000000

网关唯一标识。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=DeleteGateway&GwEui=0000000000000000&<公共请求参数>

正常返回示例

XML 格式

<DeleteGatewayResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></DeleteGatewayResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

760 文档版本:20200417

Page 773: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.7.4 GetGateway调用GetGateway获取网关信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetGateway 系统规定参数。取值:GetGateway

GwEui String 是 0000000000000000

网关唯一标识。

返回数据

名称 类型 示例值 描述

Data 网关信息。

Address String 详细地址 网关所在详细地址。

AddressCode Long 123 网关所在地区ID,由http://lbs.amap.

com/api/javascript-api/download定

义。

文档版本:20200417 761

Page 774: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

AuthTypes - STANDARD 网关合约类型。

• HYBRID:hybrid网关• SINGLE_CHANNEL:单通道网关• STANDARD:标准合约网关

ChargeStatus String NORMAL 网关欠费状态。

• NORMAL:网关未欠费,正常工作• ARREARAGE:网关欠费状态

City String 某某市 网关所在城市名称。

ClassBSupported

Boolean true 该网关是否支持Class B模式。

ClassBWorking

Boolean true 该网关是否正工作在Class B模式下。

CommunicationMode

String HALF_DUPLEX 网关通信模式。可取值

为:FULL_DUPLEX(全双

工)、HALF_DUPLEX(半双工)。

Description String 网关描述 自定义网关描述。

District String 某某区 网关所在城区名称。

EmbeddedNsId

String 123 Hybrid网关id

Enabled Boolean true 该网关是否处于启用状态。

FreqBandPlanGroupId

Long 123 网关频段ID。

GisCoordinateSystem

String GCJ_02 网关经纬度所采用的坐标系统,可取值:

WGS_84, GCJ_02。

GwEui String 0000000000000000

网关唯一标识。

Latitude Float 23.45678 网关纬度。

Longitude Float 123.45678 网关经度。

762 文档版本:20200417

Page 775: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

Name String 网关名称 自定义网关名称。

OnlineState String ONLINE 网关在离线状态。可取值为ONLINE,

OFFLINE。

OnlineStateChangedMillis

Long 1514736000000 最近一次在离线状态变更的时间。

格式为UNIX时间戳,以毫秒为单位。

TimeCorrectable

Boolean true 该网关是否可以作为时间校准网关。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetGateway&GwEui=0000000000000000&RegionId=cn-shanghai&<公共请求参数>

正常返回示例

XML 格式

<GetGatewayResponse> <Data> <City>某某市</City> <Name>网关名称</Name> <District>某某区</District> <OnlineState>ONLINE</OnlineState> <TimeCorrectable>true</TimeCorrectable> <Enabled>true</Enabled> <Longitude>123.45678</Longitude> <Latitude>23.45678</Latitude> <OnlineStateChangedMillis>1514736000000</OnlineStateChangedMillis> <ClassBSupported>true</ClassBSupported> <Address>详细地址</Address> <GwEui>0000000000000000</GwEui> <CommunicateMode>HALF_DUPLEX</CommunicateMode> <ClassBWorking>true</ClassBWorking> <FreqBandPlanGroupId>123</FreqBandPlanGroupId> <AddressCode>123</AddressCode> <GisCoordinateSystem>GCJ-02</GisCoordinateSystem> <Description>网关描述</Description>

文档版本:20200417 763

Page 776: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetGatewayResponse>

JSON 格式

{ "Data":{ "TimeCorrectable":true, "Enabled":true, "Description":"网关描述", "OnlineStateChangedMillis":1514736000000, "GisCoordinateSystem":"GCJ-02", "AddressCode":123, "ClassBSupported":true, "City":"某某市", "Name":"网关名称", "FreqBandPlanGroupId":123, "District":"某某区", "ClassBWorking":true, "Address":"详细地址", "Latitude":23.45678, "Longitude":123.45678, "OnlineState":"ONLINE", "CommunicateMode":"HALF_DUPLEX", "GwEui":"0000000000000000" }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

764 文档版本:20200417

Page 777: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.7.5 ListGateways调用ListGateways根据过滤条件查询当前用户账号名下的网关信息列表。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListGateways 系统规定参数。取值:ListGatewa

ys。

Limit Long 是 2 本次查询的网关数量上限,大于等于

1。

Offset Long 是 0 本次查询的起始位置,从0开始。

Ascending Boolean 否 false 配合SortingField参数一起使用,

true表示升序,false表示降序。

FreqBandPlanGroupId

Long 否 123 网关频段ID过滤。

FuzzyCity String 否 CityName 城市名模糊过滤。

FuzzyGwEui String 否 123456 GwEUI模糊过滤。

FuzzyName String 否 GatewayName 网关名称模糊过滤。

IsEnabled Boolean 否 true 网关启停用状态过滤。

如未传入此参数,则不限制启停状

态。

OnlineState String 否 OFFLINE 网关在离线状态过滤。

如未传入此参数,则不限制在线状

态。可取值为:ONLINE, OFFLINE

SortingField String 否 ONLINE_STATE_CHANGED_MILLIS

指定排序字段,可取值为

ONLINE_STATE_CHANGED_MILLIS

文档版本:20200417 765

Page 778: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

Data 返回的结果。

List 查询到的网关信息列表。

Address String 详细地址 网关所在详细地址。

AddressCode Long 123 网关所在地区ID,由http://lbs.amap.

com/api/javascript-api/download定

义。

AuthTypes STANDARD 网关合约类型。

• HYBRID:hybrid网关• SINGLE_CHANNEL:单通道网关• STANDARD:标准合约网关

ChargeStatus String NORMAL 网关欠费状态。

• NORMAL:网关未欠费,正常工作• ARREARAGE:网关欠费状态

City String 某某市 网关所在城市名称。

ClassBSupported

Boolean true 该网关是否支持 Class B 模式。

ClassBWorking

Boolean true 该网关是否正工作在 Class B 模式下。

CommunicationMode

String HALF_DUPLEX 网关通信模式。可取值

为FULL_DUPLEX(全双

工)、HALF_DUPLEX(半双工)。

Description String 网关描述 自定义网关描述。

District String 某某区 网关所在城区名称。

EmbeddedNsId

String 123 Hybrid网关id

Enabled Boolean true 该网关是否处于启用状态。

766 文档版本:20200417

Page 779: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

FreqBandPlanGroupId

Long 123 网关频段ID。

GisCoordinateSystem

String GCJ_02 网关经纬度所采用的坐标系统,可取值为

WGS_84,GCJ_02。

GwEui String 0000000000000000

网关唯一标识。

Latitude Float 23.45678 网关纬度。

Longitude Float 123.45678 网关经度。

Name String 网关名称 自定义网关名称。

OnlineState String ONLINE 网关在离线状态,可取值为:ONLINE,

OFFLINE。

OnlineStateChangedMillis

Long 1514736000000 最近一次在离线状态变更的时间。

格式为UNIX时间戳,以毫秒为单位。

TimeCorrectable

Boolean true 该网关是否可以作为时间校准网关。

TotalCount Long 2 满足过滤条件的网关总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListGateways&Limit=2&Offset=0&<公共请求参数>

正常返回示例

文档版本:20200417 767

Page 780: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

XML 格式

<ListGatewaysResponse> <Data> <TotalCount>23</TotalCount> <List> <Gateway> <City>某某市</City> <Name>网关名称</Name> <District>某某区</District> <OnlineState>ONLINE</OnlineState> <TimeCorrectable>true</TimeCorrectable> <Enabled>true</Enabled> <Longitude>123.45678</Longitude> <Latitude>23.45678</Latitude> <OnlineStateChangedMillis>1514736000000</OnlineStateChangedMillis> <ClassBSupported>true</ClassBSupported> <Address>详细地址</Address> <GwEui>0000000000000000</GwEui> <CommunicateMode>HALF_DUPLEX</CommunicateMode> <ClassBWorking>true</ClassBWorking> <FreqBandPlanGroupId>123</FreqBandPlanGroupId> <AddressCode>123</AddressCode> <GisCoordinateSystem>GCJ-02</GisCoordinateSystem> <Description>网关描述</Description> </Gateway> <Gateway> <City>某某市</City> <Name>网关名称</Name> <District>某某区</District> <OnlineState>ONLINE</OnlineState> <TimeCorrectable>true</TimeCorrectable> <Enabled>true</Enabled> <Longitude>123.45678</Longitude> <Latitude>23.45678</Latitude> <OnlineStateChangedMillis>1514736000000</OnlineStateChangedMillis> <ClassBSupported>true</ClassBSupported> <Address>详细地址</Address> <GwEui>0000000000000000</GwEui> <CommunicateMode>HALF_DUPLEX</CommunicateMode> <ClassBWorking>true</ClassBWorking> <FreqBandPlanGroupId>123</FreqBandPlanGroupId> <AddressCode>123</AddressCode> <GisCoordinateSystem>GCJ-02</GisCoordinateSystem> <Description>网关描述</Description> </Gateway> </List> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ListGatewaysResponse>

JSON 格式

{ "Data":{ "TotalCount":23, "List":[ { "TimeCorrectable":true,

768 文档版本:20200417

Page 781: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

"Enabled":true, "Description":"网关描述", "OnlineStateChangedMillis":1514736000000, "GisCoordinateSystem":"GCJ-02", "AddressCode":123, "ClassBSupported":true, "City":"某某市", "Name":"网关名称", "FreqBandPlanGroupId":123, "District":"某某区", "ClassBWorking":true, "Address":"详细地址", "Latitude":23.45678, "Longitude":123.45678, "OnlineState":"ONLINE", "CommunicateMode":"HALF_DUPLEX", "GwEui":"0000000000000000" }, { "TimeCorrectable":true, "Enabled":true, "Description":"网关描述", "OnlineStateChangedMillis":1514736000000, "GisCoordinateSystem":"GCJ-02", "AddressCode":123, "ClassBSupported":true, "City":"某某市", "Name":"网关名称", "FreqBandPlanGroupId":123, "District":"某某区", "ClassBWorking":true, "Address":"详细地址", "Latitude":23.45678, "Longitude":123.45678, "OnlineState":"ONLINE", "CommunicateMode":"HALF_DUPLEX", "GwEui":"0000000000000000" } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 769

Page 782: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.7.6 UpdateGateway调用UpdateGateway更新网关信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateGateway 系统规定参数。取值:UpdateGate

way。

GwEui String 是 0000000000000000

网关唯一标识。

Address String 否 详细地址 网关所在详细地址。

AddressCode Long 否 123 网关所在地区ID,由http://lbs.

amap.com/api/javascript-api/

download定义。

City String 否 某某市 网关所在城市名称。

CommunicationMode

String 否 HALF_DUPLEX 网关通信模式。可取值

为FULL_DUPLEX(全双

工)、HALF_DUPLEX(半双工)。

Description String 否 网关描述 自定义网关描述。

District String 否 某某区 网关所在城区名称。

FreqBandPlanGroupId

Long 否 123 网关频段ID。

GisCoordinateSystem

String 否 GCJ_02 网关经纬度所采用的坐标系统,可取

值为WGS_84, GCJ_02。

Latitude Float 否 23.45678 网关纬度。

Longitude Float 否 123.45678 网关经度。

Name String 否 网关名称 自定义网关名称。

770 文档版本:20200417

Page 783: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateGateway&GwEui=0000000000000000&<公共请求参数>

正常返回示例

XML 格式

<UpdateGatewayResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateGatewayResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

文档版本:20200417 771

Page 784: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 InvalidName The specified name is invalid.

名称不合法

4.1.1.7.7 UpdateGatewayEnablingState调用UpdateGatewayEnablingState启动、关闭网关。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateGatewayEnablingState

系统规定参数。取值:UpdateGate

wayEnablingState。

Enabled Boolean 是 true 是否开启网关。

• true:表示启用该网关。• false:表示关闭该网关。

GwEui String 是 0000000000000000

网关唯一标识。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateGatewayEnablingState&Enabled=true&GwEui=0000000000000000&<公共请求参数>

正常返回示例

772 文档版本:20200417

Page 785: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

XML 格式

<UpdateGatewayEnablingStateResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateGatewayEnablingStateResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

4.1.1.8 网络管理

4.1.1.8.1 AcceptJoinPermissionAuthOrder调用AcceptJoinPermissionAuthOrder接受专用入网凭证授权工单。

开发者(解决方案供应商)通过该接口接受一个由网络运营者授权的专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 AcceptJoinPermissionAuthOrder

系统规定参数。取值:AcceptJoin

PermissionAuthOrder。

文档版本:20200417 773

Page 786: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

OrderId String 是 123 要接受的授权工单ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=AcceptJoinPermissionAuthOrder&OrderId=123&<公共请求参数>

正常返回示例

XML 格式

<AcceptJoinPermissionAuthOrderResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></AcceptJoinPermissionAuthOrderResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 IllegalOrderStateTransition

The order status conversion is invalid.

工单状态转换非法

774 文档版本:20200417

Page 787: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.8.2 UpdateOwnedLocalJoinPermission调用UpdateOwnedLocalJoinPermission更新当前用户账号所拥有的专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateOwnedLocalJoinPermission

系统规定参数。取值:

UpdateOwnedLocalJoin

Permission。

JoinPermissionId

String 是 123 专用入网凭证ID,用来指定要更新的

入网凭证。

ClassMode String 否 A 专用入网凭证采用的LoRaWAN

Class模式,用于更新旧的 Class 模

式。可取值:A、B、C。

DataRate String 否 4 工作速率。

FreqBandPlanGroupId

Long 否 201 专用入网凭证所采用的频段的频段ID

,用于更新旧频段。

JoinPermissionName

String 否 凭证1 自定义入网凭证名称,用于更新旧名

称。

RxDelay String 否 1 classA的接收窗口延时。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateOwnedLocalJoinPermission&JoinPermissionId=123

文档版本:20200417 775

Page 788: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&<公共请求参数>

正常返回示例

XML 格式

<UpdateOwnedLocalJoinPermissionResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateOwnedLocalJoinPermissionResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 JoinPermissionAlreadyAuthorized

The specified join permission has already been granted to another renter.

入网凭证已经授权给了其它用户

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

400 JoinPermissionNameDuplicated

The specified join permission name already exists.

入网凭证名称重复

776 文档版本:20200417

Page 789: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 InvalidName The specified name is invalid.

名称不合法

400 InvalidFreqBandPlan

The frequency band plan is invalid.

频段计划不可用

4.1.1.8.3 SubmitJoinPermissionAuthOrder调用SubmitJoinPermissionAuthOrder发起专用入网凭证授权工单。

网络运营者可以通过该接口向开发者(解决方案供应商)授权一个专用入网凭证。不过只是发起了一

个授权工单,需待开发者接受该授权后,授权才能完成。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 SubmitJoinPermissionAuthOrder

系统规定参数。取值:SubmitJoin

PermissionAuthOrder。

JoinPermissionId

String 是 123 要授权的专用入网凭证ID。

RenterAliyunId String 是 some_user 要授权的开发者的阿里云账号ID。

返回数据

名称 类型 示例值 描述

Data Long 1234 授权工单ID。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=SubmitJoinPermissionAuthOrder&JoinPermissionId=123&RenterAliyunId=some_user&<公共请求参数>

正常返回示例

文档版本:20200417 777

Page 790: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

XML 格式

<SubmitJoinPermissionAuthOrderResponse> <Data>1234</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></SubmitJoinPermissionAuthOrderResponse>

JSON 格式

{ "Data":"1234", "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 TooManyRenterNonExistentFailures

You have entered invalid renter usernames for several times. Try again later.

被授权者账号名输入错误次数过多,请稍后再试。

400 JoinPermissionAlreadyAuthorized

The specified join permission has already been granted to another renter.

入网凭证已经授权给了其它用户

400 RenterDoesNotExist

The specified renter does not exist.

被授权的用户不存在

778 文档版本:20200417

Page 791: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.8.4 ReturnJoinPermission调用ReturnJoinPermission归还租用的入网凭证(可以是专用入网凭证或泛在入网凭证)。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ReturnJoinPermission

系统规定参数。取值:ReturnJoin

Permission。

JoinPermissionId

String 是 123 要归还的入网凭证ID。

JoinPermissionType

String 是 LOCAL 要归还的入网凭证类型。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ReturnJoinPermission&JoinPermissionId=123&JoinPermissionType=LOCAL&<公共请求参数>

正常返回示例

XML 格式

<ReturnJoinPermissionResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ReturnJoinPermissionResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

文档版本:20200417 779

Page 792: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 JoinPermissionAlreadyBoundNodeGroup

The specified join permission has already been bound to another node group.

入网凭证已经绑定了节点组

4.1.1.8.5 RejectJoinPermissionAuthOrder调用RejectJoinPermissionAuthOrder回绝专用入网凭证授权工单。

说明:

开发者(解决方案供应商)通过该接口回绝一个由网络运营者授权的专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 RejectJoinPermissionAuthOrder

系统规定参数。取值:RejectJoin

PermissionAuthOrder。

OrderId String 是 123 要回绝的授权工单ID。

780 文档版本:20200417

Page 793: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=RejectJoinPermissionAuthOrder&OrderId=123&<公共请求参数>

正常返回示例

XML 格式

<RejectJoinPermissionAuthOrderResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></RejectJoinPermissionAuthOrderResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 781

Page 794: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

400 IllegalOrderStateTransition

The order status conversion is invalid.

工单状态转换非法

4.1.1.8.6 ListRentedJoinPermissions调用ListRentedJoinPermissions根据过滤条件,查询当前用户账号所租用的入网凭证列表(可能是

专用入网凭证或泛在入网凭证)。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListRentedJoinPermissions

系统规定参数。取值:ListRented

JoinPermissions。

Limit Long 是 2 本次查询的入网凭证数量的上限,大

于等于 1。

Offset Long 是 0 本次查询的起始位置,从 0 开始。

Ascending Boolean 否 false 配合SortingField参数一起使用,

true表示升序,false表示降序。

BoundNodeGroup

Boolean 否 false 根据入网凭证是否关联到节点分组进

行过滤。true表示已关联,false表

示未关联。

Enabled Boolean 否 false 按照凭证的启停用状态进行过滤。

true表示启用,false表示停用。

FuzzyJoinEui String 否 d896e0 模糊匹配入网凭证使用的JoinEUI。

FuzzyJoinPermissionName

String 否 凭证1 模糊匹配入网凭证的名称。

782 文档版本:20200417

Page 795: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

FuzzyOwnerAliyunId

String 否 some-user 模糊匹配入网凭证拥有者的阿里云账

号ID。

SortingField String 否 CREATED_MILLIS 指定排序字段,可取值为

CREATED_MILLIS, 表示根据创建时

间排序。

Type String 否 LOCAL 按照入网凭证的类型进行过滤,取

值:

• LOCAL:专用凭证• ROAMING:泛在凭证

返回数据

名称 类型 示例值 描述

Data - - 返回的结果。

List - - 符合过滤条件的入网凭证列表。

BoundNodeGroup

Boolean false 入网凭证是否已关联到节点分组。

BoundNodeGroupId

String 123 入网凭证绑定的节点组id。

BoundNodeGroupName

String 123 入网凭证绑定的节点组名称。

ClassMode String A 入网凭证采用的LoRaWAN Class模式,可

取值:A、B、C。

DataRate String 4 工作速率。

Enabled Boolean true 入网凭证的启停用状态。

FreqBandPlanGroupId

String 102 入网凭证采用的频段的频段ID。

JoinEui String 0000000000000000

入网凭证使用的的JoinEUI。

文档版本:20200417 783

Page 796: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

JoinPermissionId

String 123 入网凭证ID。

JoinPermissionName

String 凭证1 入网凭证的名称。

OwnerAliyunId

String some-user1 • 如果该入网凭证是专用入网凭证,该字段表示拥有者的阿里云账号ID。

• 如果该入网凭证是泛在入网凭证,该字段恒为AliCloud IoT。

RxDelay String 1 classA的接收窗口延时。

Type String LOCAL 入网凭证的类型。

TotalCount Long 10 符合过滤条件的入网凭证总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListRentedJoinPermissions&Limit=2&Offset=0&<公共请求参数>

正常返回示例

XML 格式

<ListRentedJoinPermissionsResponse> <Data> <TotalCount>10</TotalCount> <List> <JoinPermission> <JoinEui>0000000000000000</JoinEui> <ClassMode>A</ClassMode> <Enabled>true</Enabled> <BoundNodeGroup>false</BoundNodeGroup> <JoinPermissionId>123</JoinPermissionId> <OwnerAliyunId>some-user1</OwnerAliyunId> <Type>LOCAL</Type> <JoinPermissionName>凭证1</JoinPermissionName> <FreqBandPlanGroupId>102</FreqBandPlanGroupId>

784 文档版本:20200417

Page 797: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

</JoinPermission> <JoinPermission> <JoinEui>0000000000000001</JoinEui> <ClassMode>A</ClassMode> <Enabled>true</Enabled> <BoundNodeGroup>false</BoundNodeGroup> <JoinPermissionId>126</JoinPermissionId> <OwnerAliyunId>some-user2</OwnerAliyunId> <Type>ROAMING</Type> <JoinPermissionName>凭证2</JoinPermissionName> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </JoinPermission> </List> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ListRentedJoinPermissionsResponse>

JSON 格式

{ "Data":{ "TotalCount":10, "List":[ { "JoinPermissionId":"123", "Enabled":true, "FreqBandPlanGroupId":102, "BoundNodeGroup":false, "OwnerAliyunId":"some-user1", "Type":"LOCAL", "JoinEui":"0000000000000000", "ClassMode":"A", "JoinPermissionName":"凭证1" }, { "JoinPermissionId":"126", "Enabled":true, "FreqBandPlanGroupId":102, "BoundNodeGroup":false, "OwnerAliyunId":"some-user2", "Type":"ROAMING", "JoinEui":"0000000000000001", "ClassMode":"A", "JoinPermissionName":"凭证2" } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

文档版本:20200417 785

Page 798: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

4.1.1.8.7 ListOwnedJoinPermissions调用ListOwnedJoinPermissions根据过滤条件,查询当前用户账号所拥有的入网凭证列表。

通过该接口获取到的当前用户账号名下的是专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListOwnedJoinPermissions

系统规定参数。取值:ListOwnedJ

oinPermissions。

Limit Long 是 2 本次查询的入网凭证的数量上限,大

于等于 1。

Offset Long 是 0 本次查询的起始位置,从 0 开始。

Ascending Boolean 否 true 配合SortingField参数一起使用,

true表示升序,false表示降序。

Enabled Boolean 否 false 根据入网凭证的启停用状态过滤。

FuzzyJoinEui String 否 d896e0 模糊匹配入网凭证所使用的JoinEUI

FuzzyJoinPermissionName

String 否 凭证1 模糊匹配入网凭证的名称。

FuzzyRenterAliyunId

String 否 some-user 模糊匹配入网凭证租户的阿里云账号

ID。

786 文档版本:20200417

Page 799: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

SortingField String 否 CREATED_MILLIS 指定排序字段,可取值为

CREATED_MILLIS, 表示根据创建时

间排序。

返回数据

名称 类型 示例值 描述

Data 返回的结果。

List 符合过滤条件的入网凭证列表。

AuthState String NEW 入网凭证的授权状态。取值:

• NEW:未授权• APPLYING:授权中• ACCEPTED:已授权

ClassMode String A 入网凭证采用的LoRaWAN Class模式,可

取值:A、B、C。

DataRate Long 4 工作速率。

Enabled Boolean true 入网凭证的启停用状态。

FreqBandPlanGroupId

Long 102 入网凭证采用的频段的频段ID。

JoinEui String 0000000000000000

入网凭证使用的JoinEUI。

JoinPermissionId

String 102 入网凭证的ID。

JoinPermissionName

String 凭证1 入网凭证的名称。

RenterAliyunId

String some-user1 入网凭证租户的阿里云账号ID。

RxDelay Long 1 classA的接收窗口延时。

TotalCount Long 10 符合过滤条件的入网凭证总数。

文档版本:20200417 787

Page 800: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListOwnedJoinPermissions&Limit=2&Offset=0&<公共请求参数>

正常返回示例

XML 格式

<ListOwnedJoinPermissionsResponse> <Data> <TotalCount>10</TotalCount> <List> <JoinPermission> <JoinEui>0000000000000000</JoinEui> <ClassMode>A</ClassMode> <Enabled>true</Enabled> <RenterAliyunId>some-user1</RenterAliyunId> <JoinPermissionId>123</JoinPermissionId> <AuthState>ACCEPTED</AuthState> <JoinPermissionName>凭证1</JoinPermissionName> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </JoinPermission> <JoinPermission> <JoinEui>0000000000000001</JoinEui> <ClassMode>A</ClassMode> <Enabled>true</Enabled> <RenterAliyunId>some-user2</RenterAliyunId> <JoinPermissionId>126</JoinPermissionId> <AuthState>ACCEPTED</AuthState> <JoinPermissionName>凭证2</JoinPermissionName> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </JoinPermission> </List> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ListOwnedJoinPermissionsResponse>

JSON 格式

{ "Data":{ "TotalCount":10, "List":[

788 文档版本:20200417

Page 801: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

{ "JoinPermissionId":"123", "Enabled":true, "RenterAliyunId":"some-user1", "FreqBandPlanGroupId":102, "JoinEui":"0000000000000000", "ClassMode":"A", "AuthState":"ACCEPTED", "JoinPermissionName":"凭证1" }, { "JoinPermissionId":"126", "Enabled":true, "RenterAliyunId":"some-user2", "FreqBandPlanGroupId":102, "JoinEui":"0000000000000001", "ClassMode":"A", "AuthState":"ACCEPTED", "JoinPermissionName":"凭证2" } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

文档版本:20200417 789

Page 802: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.8.8 GetRentedJoinPermission调用GetRentedJoinPermission根据入网凭证ID,获取当前用户账号租用的入网凭证(可能是专用入

网凭证或泛在入网凭证)。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetRentedJoinPermission

系统规定参数。取值:GetRentedJ

oinPermission。

JoinPermissionId

String 是 123 入网凭证ID。

返回数据

名称 类型 示例值 描述

Data 租用的入网凭证信息列表。

BoundNodeGroupId

String 123 凭证绑定的节点组id。

BoundNodeGroupName

String 123 凭证绑定的节点组名称。

ClassMode String A 入网凭证采用的LoRaWAN Class模式,可

取值:A、B、C。

CreateMillis Long 1514736000000 入网凭证的创建时间,格式为 UNIX 时间

戳,以毫秒为单位。

DataRate Long 2 工作速率。

Enabled Boolean true 入网凭证的启停用状态。true表示启用,

false表示停用。

FreqBandPlanGroupId

Long 102 入网凭证采用的频段的频段ID。

JoinEui String 0000000000000000

入网凭证使用的JoinEUI。

JoinPermissionId

String 123 入网凭证ID。

790 文档版本:20200417

Page 803: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

JoinPermissionName

String 凭证1 入网凭证的名称。

NodesCnt Long 10 使用该入网凭证的节点数量。

RxDailySum Long 0 入网凭证的当天上行数据包量。

RxDelay Long 1 classA的接收窗口延时。

RxMonthSum Long 0 入网凭证的当月上行数据包量。

TxDailySum Long 0 入网凭证的当天下行数据包量。

TxMonthSum Long 0 入网凭证的当月下行数据包量。

Type String LOCAL 入网凭证的类型。取值:

• LOCAL:专用凭证。• ROAMING:泛在凭证。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http(s)://POP网关域名/?Action=GetRentedJoinPermission&JoinPermissionId=123&<公共请求参数>

正常返回示例

XML 格式

<GetRentedJoinPermissionResponse> <Data> <JoinEui>0000000000000000</JoinEui> <ClassMode>A</ClassMode> <RxDailySum>0</RxDailySum> <Enabled>true</Enabled> <CreateMillis>1514736000000</CreateMillis> <RxMonthSum>0</RxMonthSum> <TxDailySum>0</TxDailySum> <NodesCnt>10</NodesCnt>

文档版本:20200417 791

Page 804: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<TxMonthSum>0</TxMonthSum> <JoinPermissionId>123</JoinPermissionId> <type>LOCAL</type> <JoinPermissionName>凭证1</JoinPermissionName> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetRentedJoinPermissionResponse>

JSON 格式

{ "Data":{ "Enabled":true, "NodesCnt":10, "RxDailySum":0, "JoinEui":"0000000000000000", "ClassMode":"A", "type":"LOCAL", "JoinPermissionName":"凭证1", "JoinPermissionId":"123", "FreqBandPlanGroupId":102, "TxDailySum":0, "TxMonthSum":0, "CreateMillis":1514736000000, "RxMonthSum":0 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.8.9 GetOwnedJoinPermission调用GetOwnedJoinPermission根据入网凭证ID获取当前用户账号所拥有的入网凭证。

说明:

792 文档版本:20200417

Page 805: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

通过该接口获取的一定是当前用户账号所拥有的某个专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetOwnedJoinPermission

系统规定参数。取值:GetOwnedJo

inPermission。

JoinPermissionId

String 是 123 要获取的入网凭证的ID。

返回数据

名称 类型 示例值 描述

Data 所拥有入网凭证的信息列表。

AuthState String NEW 入网凭证的授权状态。取值:

• NEW:未授权• APPLYING:授权中• ACCEPTED:已授权

ClassMode String A 入网凭证采用的LoRaWAN Class模式。取

值:A、B、C。

CreateMillis Long 1514736000000 入网凭证的创建时间。格式为 UNIX 时间

戳,单位毫秒。

DataDispatchDestination

String IOT 数据流转目的地。取值为IOT:数据流转

到IoT的产品。

DataRate Long 4 工作速率。

Enabled Boolean true 入网凭证的启停用状态。

FreqBandPlanGroupId

Long 102 入网凭证所采用的频段的频段ID。

JoinEui String 0000000000000000

入网凭证所使用的JoinEUI。

JoinPermissionId

String 123 入网凭证ID。

文档版本:20200417 793

Page 806: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

JoinPermissionName

String 凭证1 入网凭证的名称。

MulticastEnabled

Boolean false 入网凭证组播的启停用状态。

MulticastNodeCapacity

Integer 1000 入网凭证可接入组播节点容量。

MulticastNodeCount

Integer 10 入网凭证已接入组播节点数量。

NodesCnt Long 10 使用该入网凭证的节点的数量。

RenterAliyunId

String some-user 入网凭证租户的阿里云账号ID。

RxDailySum Long 0 入网凭证的当天上行数据包量。

RxDelay Long 1 classA的接收窗口延时。

RxMonthSum Long 0 入网凭证的当月上行数据包量。

TxDailySum Long 0 入网凭证的当天下行数据包量。

TxMonthSum Long 0 入网凭证的当月下行数据包量。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetOwnedJoinPermission&JoinPermissionId=123&<公共请求参数>

正常返回示例

XML 格式

<GetOwnedJoinPermissionResponse> <Data> <JoinEui>0000000000000000</JoinEui>

794 文档版本:20200417

Page 807: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<ClassMode>A</ClassMode> <RxDailySum>0</RxDailySum> <Enabled>true</Enabled> <CreateMillis>1514736000000</CreateMillis> <RxMonthSum>0</RxMonthSum> <RenterAliyunId>some-user</RenterAliyunId> <TxDailySum>0</TxDailySum> <NodesCnt>10</NodesCnt> <TxMonthSum>0</TxMonthSum> <JoinPermissionId>123</JoinPermissionId> <DataDispatchDestination>IOT</DataDispatchDestination> <JoinPermissionName>凭证1</JoinPermissionName> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetOwnedJoinPermissionResponse>

JSON 格式

{ "Data":{ "Enabled":true, "NodesCnt":10, "DataDispatchDestination":"IOT", "RenterAliyunId":"some-user", "RxDailySum":0, "JoinEui":"0000000000000000", "ClassMode":"A", "JoinPermissionName":"凭证1", "JoinPermissionId":"123", "FreqBandPlanGroupId":102, "TxDailySum":0, "TxMonthSum":0, "CreateMillis":1514736000000, "RxMonthSum":0 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 795

Page 808: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.8.10 GetJoinPermissionAuthOrder调用GetJoinPermissionAuthOrder获取专用凭证授权工单的详细信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetJoinPermissionAuthOrder

系统规定参数。取值:GetJoinPer

missionAuthOrder。

OrderId String 是 123 授权工单ID。

返回数据

名称 类型 示例值 描述

Data 授权工单的详细信息。

AcceptedMillis Long 1514736000000 工单被接受的 UNIX 时间戳,以毫秒为单

位。

ApplyingMillis Long 1514736000000 发起工单的 UNIX 时间戳,以毫秒为单

位。

CanceledMillis Long 1514736000000 工单被取消的 UNIX 时间戳,以毫秒为单

位。

JoinPermissionId

String 123456 要授权的专用入网凭证ID。

OrderId String 123 授权工单ID。

OrderState String ACCEPTED 工单状态。取值:

• APPLYING:工单发起,等待目标租户处理。

• ACCEPTED:工单被接受。• REJECTED:工单被回绝。• CANCELED:工单被取消。

796 文档版本:20200417

Page 809: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

OwnerAliyunId

String some_user 发起授权的专用入网凭证拥有者的阿里云

账号ID。

RejectedMillis Long 1514736000000 工单被回绝的 UNIX 时间戳,以毫秒为单

位。

RenterAliyunId

String some_user 专用入网凭证的目标租户的阿里云账号ID

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetJoinPermissionAuthOrder&OrderId=123&<公共请求参数>

正常返回示例

XML 格式

<GetJoinPermissionAuthOrderResponse> <Data> <OrderId>123</OrderId> <CanceledMillis>1514736000000</CanceledMillis> <RejectedMillis>1514736000000</RejectedMillis> <ApplyingMillis>1514736000000</ApplyingMillis> <RenterAliyunId>some_user</RenterAliyunId> <OrderState>ACCEPTED</OrderState> <OwnerAliyunId>some_user</OwnerAliyunId> <JoinPermissionId>123456</JoinPermissionId> <AcceptedMillis>1514736000000</AcceptedMillis> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetJoinPermissionAuthOrderResponse>

JSON 格式

{ "Data":{ "JoinPermissionId":"123456", "CanceledMillis":1514736000000, "OrderState":"ACCEPTED",

文档版本:20200417 797

Page 810: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

"RenterAliyunId":"some_user", "OwnerAliyunId":"some_user", "RejectedMillis":1514736000000, "OrderId":"123", "ApplyingMillis":1514736000000, "AcceptedMillis":1514736000000 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.8.11 DeleteLocalJoinPermission调用DeleteLocalJoinPermission删除当前用户账号所拥有的专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 DeleteLocalJoinPermission

系统规定参数。取值:DeleteLoca

lJoinPermission。

JoinPermissionId

String 是 123 要删除的专用入网凭证的ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

798 文档版本:20200417

Page 811: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

Success Boolean true 是否成功。

示例

请求示例

正常返回示例

XML 格式

<DeleteLocalJoinPermissionResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></DeleteLocalJoinPermissionResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 JoinPermissionAlreadyAuthorized

The specified join permission has already been granted to another renter.

入网凭证已经授权给了其它用户

文档版本:20200417 799

Page 812: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.8.12 CreateLocalJoinPermission调用CreateLocalJoinPermission创建专用入网凭证。当前用户账号将成为该凭证的拥有者,拥有该

凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CreateLocalJoinPermission

系统规定参数。取值:CreateLoca

lJoinPermission。

ClassMode String 是 A 专用入网凭证采用的LoRaWAN

Class模式。可取值:A、B、C。

FreqBandPlanGroupId

Long 是 101 专用入网凭证所采用的频段的频段ID

JoinPermissionName

String 是 test 自定义专用入网凭证名称。

UseDefaultJoinEui

Boolean 是 true 专用入网凭证是否使用阿里云统一

JoinEUI。

DataRate Long 否 4 工作速率。

RxDelay Long 否 1 classA的接收窗口延时。

返回数据

名称 类型 示例值 描述

Data String 123 所创建的专用入网凭证的ID。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CreateLocalJoinPermission&ClassMode=A

800 文档版本:20200417

Page 813: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&FreqBandPlanGroupId=101&JoinPermissionName=test&UseDefaultJoinEui=true&<公共请求参数>

正常返回示例

XML 格式

<CreateLocalJoinPermissionResponse> <Data>123</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CreateLocalJoinPermissionResponse>

JSON 格式

{ "Data":"123", "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 ExceedLocalJoinPermissionLimit

The maximum number of local join permissions that you can create is exceeded.

超出本地凭证已购买额度

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 JoinPermissionNameDuplicated

The specified join permission name already exists.

入网凭证名称重复

400 InvalidName The specified name is invalid.

名称不合法

400 InvalidFreqBandPlan

The frequency band plan is invalid.

频段计划不可用

文档版本:20200417 801

Page 814: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.8.13 CountRentedJoinPermissions调用CountRentedJoinPermissions统计当前用户账号所租用的且符合过滤条件的入网凭证数量。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountRentedJoinPermissions

系统规定参数。取值:CountRente

dJoinPermissions。

BoundNodeGroup

Boolean 否 true 根据入网凭证是否关联到节点分组进

行过滤。

true表示已关联,false表示未关

联。

Enabled Boolean 否 true 按照凭证的启停用状态进行过滤。

FuzzyJoinEui String 否 d896e0 模糊匹配入网凭证的JoinEUI。

FuzzyJoinPermissionName

String 否 test 模糊匹配入网凭证的名称。

FuzzyOwnerAliyunId

String 否 some-user 模糊匹配入网凭证拥有者的阿里云账

号ID。

Type String 否 LOCAL 按照凭证的类型进行过滤。取值:

• LOCAL:专用凭证• ROAMING:泛在凭证

返回数据

名称 类型 示例值 描述

Data Long 100 满足过滤条件的入网凭证总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

802 文档版本:20200417

Page 815: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

示例

请求示例

http://POP网关域名/?Action=CountRentedJoinPermissions&<公共请求参数>

正常返回示例

XML 格式

<CountRentedJoinPermissionsResponse> <Data>100</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CountRentedJoinPermissionsResponse>

JSON 格式

{ "Data":100, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.8.14 CountOwnedJoinPermissions调用CountOwnedJoinPermissions统计符合过滤条件的当前用户账号所拥有的入网凭证的数量。

说明:

能够被用户账号“拥有”的入网凭证一定是专用入网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountOwnedJoinPermissions

系统规定参数。取值:

CountOwnedJoinPermissions。

文档版本:20200417 803

Page 816: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

Enabled Boolean 否 true 按照凭证的启停用状态进行过滤。

true表示启用,false表示停用。

FuzzyJoinEui String 否 d896e0 模糊匹配入网凭证使用的JoinEUI。

FuzzyJoinPermissionName

String 否 test 模糊匹配入网凭证的名称。

FuzzyRenterAliyunId

String 否 some-user 模糊匹配入网凭证租户的阿里云账号

ID。

返回数据

名称 类型 示例值 描述

Data Long 100 满足过滤条件的入网凭证总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CountOwnedJoinPermissions&<公共请求参数>

正常返回示例

XML 格式

<CountOwnedJoinPermissionsResponse> <Data>100</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CountOwnedJoinPermissionsResponse>

JSON 格式

{ "Data":100, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

804 文档版本:20200417

Page 817: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.8.15 CancelJoinPermissionAuthOrder调用CancelJoinPermissionAuthOrder取消专用入网凭证授权工单。

网络运营者可以通过该接口取消一个尚未被接受的授权工单。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CancelJoinPermissionAuthOrder

系统规定参数。取值:CancelJoin

PermissionAuthOrder。

OrderId String 是 123 要撤销的授权工单ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CancelJoinPermissionAuthOrder&OrderId=123&<公共请求参数>

正常返回示例

文档版本:20200417 805

Page 818: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

XML 格式

<CancelJoinPermissionAuthOrderResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CancelJoinPermissionAuthOrderResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 IllegalOrderStateTransition

The order status conversion is invalid.

工单状态转换非法

4.1.1.8.16 UpdateOwnedLocalJoinPermissionEnablingState调用UpdateOwnedLocalJoinPermissionEnablingState启用、停用当前用户账号所拥有的专用入

网凭证。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateOwnedLocalJoinPermissionEnablingState

系统规定参数。取值:

UpdateOwnedLocalJoin

PermissionEnablingState。

Enabled Boolean 是 true true为启用,false为停用。

JoinPermissionId

String 是 123 要操作的专用入网凭证ID。

806 文档版本:20200417

Page 819: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateOwnedLocalJoinPermissionEnablingState&Enabled=true&JoinPermissionId=123&<公共请求参数>

正常返回示例

XML 格式

<UpdateOwnedLocalJoinPermissionEnablingStateResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateOwnedLocalJoinPermissionEnablingStateResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 807

Page 820: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.9 节点管理

4.1.1.9.1 AddNodeToGroup调用AddNodeToGroup在节点分组中增加新的节点。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 AddNodeToGroup

系统规定参数。取值:

AddNodeToGroup。

DevEui String 是 0000000000000000

节点的DevEUI。

NodeGroupId String 是 123 节点分组ID。

PinCode String 是 123456 节点的PIN Code。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=AddNodeToGroup&DevEui=0000000000000000&NodeGroupId=123&PinCode=123456

808 文档版本:20200417

Page 821: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&<公共请求参数>

正常返回示例

XML 格式

<AddNodeToGroupResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></AddNodeToGroupResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 ExceedNodeLimit The maximum number of nodes is exceeded.

超出节点可使用额度

400 NodeGroupDoesNotExist

The specified node group does not exist.

节点组不存在

400 DevEuiDuplicated A node with the same devEui already exists.

节点重复添加

400 NodeAlreadyAdded

The specified node has already been added to another node group.

节点已经添加到其他分组

400 InvalidPinCode An error occurred while verifying PinCode.

PinCode校验失败

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

400 NodeDoesNotExist The specified node does not exist.

节点不存在

文档版本:20200417 809

Page 822: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.9.2 UpdateDataDispatchEnablingState调用UpdateDataDispatchEnablingState启停节点分组的数据流转。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateDataDispatchEnablingState

系统规定参数。取值:UpdateData

DispatchEnablingState。

DataDispatchEnabled

Boolean 是 true • true:表示启用数据流转• false:表示停用数据流转

NodeGroupId String 是 123 节点分组ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateDataDispatchEnablingState&DataDispatchEnabled=true&NodeGroupId=123&<公共请求参数>

正常返回示例

XML 格式

<UpdateDataDispatchEnablingStateResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateDataDispatchEnablingStateResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

810 文档版本:20200417

Page 823: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

4.1.1.9.3 UpdateDataDispatchConfig调用UpdateDataDispatchConfig更新节点分组的数据流转配置。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateDataDispatchConfig

系统规定参数。取值:UpdateData

DispatchConfig。

DataDispatchDestination

String 是 IOT 数据流转目的地。取值:IOT:数据

流转到IoT的产品。

NodeGroupId String 是 123 要更新的节点分组ID。

ProductKey String 否 xxxxxxxx 数据流转目的地为IoT的Product Key

ProductName String 否 产品1 数据流转目的地为IoT的产品名称。

文档版本:20200417 811

Page 824: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

ProductType String 否 IOT_SUITE 数据流转目的地为IoT的产品类型。

取值:

• IOT_SUITE:数据流转到 IoT 套件基础版。

• IOT_SUITE_SENIOR:数据流转到 IoT 套件高级版。

UplinkRegionName

String 否 cn-beijing 数据流转目的地为MQ的上行Region

Id。

UplinkTopic String 否 cn-shanghai 数据流转目的地为MQ的上行Topic。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateDataDispatchConfig&DataDispatchDestination=IOT&NodeGroupId=123&<公共请求参数>

正常返回示例

XML 格式

<UpdateDataDispatchConfigResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateDataDispatchConfigResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

812 文档版本:20200417

Page 825: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.9.4 UnbindJoinPermissionFromNodeGroup调用UnbindJoinPermissionFromNodeGroup接触入网凭证和节点分组的关联。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UnbindJoinPermissionFromNodeGroup

系统规定参数。取值:UnbindJoin

PermissionFromNodeGroup。

JoinPermissionId

String 是 123456 参与关联的入网凭证ID。

NodeGroupId String 是 123 要接触关联的节点分组ID。

文档版本:20200417 813

Page 826: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UnbindJoinPermissionFromNodeGroup&<公共请求参数>

正常返回示例

XML 格式

<UnbindJoinPermissionFromNodeGroupResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UnbindJoinPermissionFromNodeGroupResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

814 文档版本:20200417

Page 827: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

4.1.1.9.5 RemoveNodeFromGroup调用RemoveNodeFromGroup从节点分组中移除节点。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 RemoveNodeFromGroup

系统规定参数。取值:

RemoveNodeFromGroup。

DevEui String 是 0000000000000000

要移除的节点的DevEUI。

NodeGroupId String 是 123 节点分组ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=RemoveNodeFromGroup&DevEui=0000000000000000&NodeGroupId=123&<公共请求参数>

正常返回示例

XML 格式

<RemoveNodeFromGroupResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success>

文档版本:20200417 815

Page 828: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

</RemoveNodeFromGroupResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

400 NodeGroupDoesNotExist

The specified node group does not exist.

节点组不存在

400 NodeDoesNotExist The specified node does not exist.

节点不存在

4.1.1.9.6 ListNodesByOwnedJoinPermissionId调用ListNodesByOwnedJoinPermissionId根据过滤条件,查询使用了特定入网凭证的节点列表。

所指定的入网凭证必须时当前用户账号所拥有的入网凭证。

816 文档版本:20200417

Page 829: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListNodesByOwnedJoinPermissionId

系统规定参数。取值:ListNodesB

yOwnedJoinPermissionId。

JoinPermissionId

String 是 123 入网凭证ID。

Limit Long 是 2 本次查询的节点数量上限,大于等于

1。

Offset Long 是 0 本次查询的起始位置,从0开始。

Ascending Boolean 否 true 配合SortingField参数一起使用,

true表示升序,false表示降序。

FuzzyDevEui String 否 d896e0 模糊匹配节点的DevEUI。

SortingField String 否 CREATED_MILLIS 指定排序字段,可取值为

CREATED_MILLIS, 表示根据创建时

间排序。

返回数据

名称 类型 示例值 描述

Data 返回的结果。

List 满足过滤条件的节点列表。

BoundMillis Long 1514736000000 节点加入当前节点分组的时间,UNIX时间

戳,以毫秒为单位。

ClassMode String A 节点所采用的LoRaWAN Class模式,可取

值:A、B、C。

DevAddr String 12345678 节点的网络地址。

DevEui String 0000000000000000

节点的DevEUI。

文档版本:20200417 817

Page 830: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

LastJoinMillis Long 1514736000000 最近一次入网的时间,UNIX时间戳,以毫

秒为单位。

TotalCount Long 10 满足过滤条件的节点总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListNodesByOwnedJoinPermissionId&JoinPermissionId=123&Limit=2&Offset=0&<公共请求参数>

正常返回示例

XML 格式

<ListNodesByOwnedJoinPermissionIdResponse> <Data> <TotalCount>10</TotalCount> <List> <Node> <ClassMode>A</ClassMode> <BoundMillis>1514736000000</BoundMillis> <LastJoinMillis>1514736000000</LastJoinMillis> <DevEui>0000000000000000</DevEui> <DevAddr>12345678</DevAddr> </Node> <Node> <ClassMode>A</ClassMode> <BoundMillis>1514736000001</BoundMillis> <LastJoinMillis>1514736000000</LastJoinMillis> <DevEui>0000000000000001</DevEui> <DevAddr>12345678</DevAddr> </Node> </List> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ListNodesByOwnedJoinPermissionIdResponse>

JSON 格式

{

818 文档版本:20200417

Page 831: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

"Data":{ "TotalCount":10, "List":[ { "DevEui":"0000000000000000", "ClassMode":"A", "BoundMillis":1514736000000, "DevAddr":"12345678", "LastJoinMillis":1514736000000 }, { "DevEui":"0000000000000001", "ClassMode":"A", "BoundMillis":1514736000001, "DevAddr":"12345678", "LastJoinMillis":1514736000000 } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

4.1.1.9.7 ListNodesByNodeGroupId调用ListNodesByNodeGroupId根据过滤条件,查询指定节点分组中的节点列表。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListNodesByNodeGroupId

系统规定参数。取值:ListNodesB

yNodeGroupId。

文档版本:20200417 819

Page 832: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

Limit Long 是 2 本次查询的节点数量上限,大于等于

1。

NodeGroupId String 是 123 节点分组ID。

Offset Long 是 0 本次查询的起始位置,从0开始。

Ascending Boolean 否 true 配合SortingField参数一起使用,

true表示升序,false表示降序。

FuzzyDevEui String 否 d896e0 模糊匹配节点的DevEUI。

SortingField String 否 CREATED_MILLIS 指定排序字段,可取值为

CREATED_MILLIS,表示根据创建时

间排序。

返回数据

名称 类型 示例值 描述

Data 返回的结果。

List 满足过滤条件的节点列表。

AuthTypes STANDARD 网关合约类型。

• HYBRID:hybrid网关• SINGLE_CHANNEL:单通道网关• STANDARD:标准合约网关

BoundMillis Long 1514736000000 节点加入当前节点分组的时间,UNIX时间

戳,以毫秒为单位。

ClassMode String A 节点所采用的LoRaWAN Class模式,可取

值:A、B、C。

DevAddr String 12345678 节点的网络地址。

DevEui String 0000000000000000

节点的DevEUI。

820 文档版本:20200417

Page 833: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

LastJoinMillis Long 1514736000000 最近一次入网的时间,UNIX时间戳,以毫

秒为单位。

MulticastGroupId

String xxxx 组播ID值。

TotalCount Long 10 满足过滤条件的节点总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListNodesByNodeGroupId&Limit=2&NodeGroupId=123&Offset=0&<公共请求参数>

正常返回示例

XML 格式

<ListNodesByNodeGroupIdResponse> <Data> <TotalCount>10</TotalCount> <List> <Node> <ClassMode>A</ClassMode> <BoundMillis>1514736000000</BoundMillis> <LastJoinMillis>1514736000000</LastJoinMillis> <DevEui>0000000000000000</DevEui> <DevAddr>12345678</DevAddr> </Node> <Node> <ClassMode>A</ClassMode> <BoundMillis>1514736000001</BoundMillis> <LastJoinMillis>1514736000000</LastJoinMillis> <DevEui>0000000000000001</DevEui> <DevAddr>12345678</DevAddr> </Node> </List> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success>

文档版本:20200417 821

Page 834: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

</ListNodesByNodeGroupIdResponse>

JSON 格式

{ "Data":{ "TotalCount":10, "List":[ { "DevEui":"0000000000000000", "ClassMode":"A", "BoundMillis":1514736000000, "DevAddr":"12345678", "LastJoinMillis":1514736000000 }, { "DevEui":"0000000000000001", "ClassMode":"A", "BoundMillis":1514736000001, "DevAddr":"12345678", "LastJoinMillis":1514736000000 } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

822 文档版本:20200417

Page 835: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.9.8 ListNodeGroups调用ListNodeGroups查询当前用户账号的符合过滤条件的节点分组列表。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListNodeGroups 系统规定参数。取值:ListNodeGr

oups。

Limit Long 是 2 本次查询的分组数量上限,大于等于

1。

Offset Long 是 0 本次查询的起始位置,从0开始。

Ascending Boolean 否 true 配合SortingField参数一起使用,

true表示升序,false表示降序。

FuzzyDevEui String 否 d896e0 模糊匹配分组中的节点DevEUI。

FuzzyJoinEui String 否 d896e0 模糊匹配节点分组所使用的JoinEUI

FuzzyName String 否 test 模糊匹配节点分组名称。

SortingField String 否 CREATED_MILLIS 指定排序字段,可取值为

CREATED_MILLIS, 表示根据创建时

间排序。

返回数据

名称 类型 示例值 描述

Data 返回的结果。

List 满足过滤条件的节点分组列表。

ClassMode String A 节点分组中的节点所采用的LoRaWAN

Class模式,与分组所关联的入网凭证中指

定的一致。

文档版本:20200417 823

Page 836: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

CreateMillis Long 1514736000000 节点分组的创建时间,格式为UNIX时间

戳,以毫秒为单位。

DataDispatchConfig

节点分组的数据流转配置。

Destination String IOT 数据流转目的地。取值为IOT:数据流转

到IoT的产品。

IotProduct 如果流转目的地是IoT产品,该字段存储产

品信息。

ProductKey String xxxxxxxx 产品Product Key。

ProductName String 产品名 产品名。

ProductType String IOT_SUITE 产品类型。

OnsTopics 如果流转目的地是MQ,该字段存储MQ

Topic信息。

DownlinkRegionName

String cn-beijing MQ 下行 Region Id。

DownlinkTopic

String topic1 MQ 下行 Topic。

UplinkRegionName

String cn-shanghai MQ 上行 Region Id。

UplinkTopic String topic2 MQ 上行 Topic。

DataDispatchEnabled

Boolean true 节点分组的数据流转启停状态,true表示

启用,false表示停用。

FreqBandPlanGroupId

Long 102 节点分组中的节点所采用的频段的频段

ID,与分组所关联的入网凭证中指定的一

致。

824 文档版本:20200417

Page 837: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

JoinEui String 0000000000000000

节点分组中的节点所使用的JoinEUI,与分

组所关联的入网凭证中指定的JoinEUI一

致。

JoinPermissionEnabled

Boolean true 与节点分组关联的入网凭证的启停状态,

true表示启用,false表示停用。

JoinPermissionId

String 123456 与节点分组关联的入网凭证的ID。

JoinPermissionOwnerAliyunId

String some-user2 • 如果关联的是专用入网凭证,该字段表示入网凭证的拥有者的阿里云账号ID。

• 如果关联的是泛在入网凭证,该字段的值恒为AliCloud IoT。

JoinPermissionType

String LOCAL 与节点分组关联的入网凭证类型。取值:

• LOCAL:专用凭证• ROAMING:泛在凭证

Locks 节点分组所关联的操作锁列表。

CreateMillis Long 1514736000000 锁的创建时间。

Enabled Boolean true 锁的启停用状态。

LockId String 123 锁ID。

LockType String WRITE 锁的类型。取值:WRITE,所有写操作都

加锁,包括编辑、删除等。

NodeGroupId String 123456 节点分组ID。

NodeGroupName

String 节点分组名称2 节点分组的名称。

NodesCnt Long 10 节点分组中的节点数量。

RxDailySum Long 0 与节点分组关联的入网凭证的当天上行数

据包量。

文档版本:20200417 825

Page 838: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

RxMonthSum Long 0 与节点分组关联的入网凭证的当月上行数

据包量。

TxDailySum Long 0 与节点分组关联的入网凭证的当天下行数

据包量。

TxMonthSum Long 0 与节点分组关联的入网凭证的当月下行数

据包量。

TotalCount Long 10 满足过滤条件的节点分组总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListNodeGroups&Limit=2&Offset=0&<公共请求参数>

正常返回示例

XML 格式

<ListNodeGroupsResponse> <Data> <TotalCount>10</TotalCount> <List> <NodeGroup> <NodesCnt>10</NodesCnt> <JoinEui>0000000000000000</JoinEui> <JoinPermissionOwnerAliyunId>some-user2</JoinPermissionOwnerAliyunId> <RxDailySum>0</RxDailySum> <JoinPermissionType>LOCAL</JoinPermissionType> <ClassMode>A</ClassMode> <NodeGroupId>123456</NodeGroupId> <DataDispatchEnabled>true</DataDispatchEnabled> <Locks> <Lock> <LockId>123</LockId> <CreateMillis>1514736000000</CreateMillis> <Enabled>true</Enabled>

826 文档版本:20200417

Page 839: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<LockType>WRITE</LockType> </Lock> <Lock> <LockId>126</LockId> <CreateMillis>1514736000000</CreateMillis> <Enabled>true</Enabled> <LockType>WRITE</LockType> </Lock> </Locks> <JoinPermissionEnabled>true</JoinPermissionEnabled> <TxDailySum>0</TxDailySum> <TxMonthSum>0</TxMonthSum> <DataDispatchConfig> <Destination>IOT</Destination> <IotProduct> <ProductKey>xxxxxxxx</ProductKey> <ProductType>IOT_SUITE</ProductType> <ProductName>产品名</ProductName> </IotProduct> </DataDispatchConfig> <CreateMillis>1514736000000</CreateMillis> <NodeGroupName>节点分组名称2</NodeGroupName> <RxMonthSum>0</RxMonthSum> <JoinPermissionId>123456</JoinPermissionId> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </NodeGroup> <NodeGroup> <NodesCnt>10</NodesCnt> <JoinEui>0000000000000001</JoinEui> <JoinPermissionOwnerAliyunId>some-user2</JoinPermissionOwnerAliyunId> <RxDailySum>0</RxDailySum> <JoinPermissionType>LOCAL</JoinPermissionType> <ClassMode>A</ClassMode> <NodeGroupId>1234569</NodeGroupId> <DataDispatchEnabled>true</DataDispatchEnabled> <Locks> <Lock> <LockId>123</LockId> <LockSmithPlatformSource>LP</LockSmithPlatformSource> <Enabled>true</Enabled> <LockSmith>nmsUser1</LockSmith> <CreateMillis>1514736000000</CreateMillis> <LockType>WRITE</LockType> </Lock> <Lock> <LockId>126</LockId> <LockSmithPlatformSource>LP</LockSmithPlatformSource> <Enabled>true</Enabled> <LockSmith>nmsUser1</LockSmith> <CreateMillis>1514736000000</CreateMillis> <LockType>WRITE</LockType> </Lock> </Locks> <JoinPermissionEnabled>true</JoinPermissionEnabled> <TxDailySum>0</TxDailySum> <TxMonthSum>0</TxMonthSum> <DataDispatchConfig> <Destination>IOT</Destination> <IotProduct> <ProductKey>xxxxxxxx</ProductKey> <ProductType>IOT_SUITE</ProductType> <ProductName>产品名</ProductName> </IotProduct>

文档版本:20200417 827

Page 840: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

</DataDispatchConfig> <CreateMillis>1514736000000</CreateMillis> <NodeGroupName>节点分组名称2</NodeGroupName> <RxMonthSum>0</RxMonthSum> <JoinPermissionId>1234569</JoinPermissionId> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </NodeGroup> </List> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></ListNodeGroupsResponse>

JSON 格式

{ "Data":{ "TotalCount":10, "List":[ { "DataDispatchConfig":{ "IotProduct":{ "ProductKey":"xxxxxxxx", "ProductType":"IOT_SUITE", "ProductName":"产品名" }, "Destination":"IOT" }, "NodeGroupId":"123456", "NodesCnt":10, "Locks":[ { "LockId":"123", "Enabled":true, "CreateMillis":1514736000000, "LockType":"WRITE" }, { "LockId":"126", "Enabled":true, "CreateMillis":1514736000000, "LockType":"WRITE" } ], "RxDailySum":0, "JoinEui":"0000000000000000", "ClassMode":"A", "JoinPermissionEnabled":true, "JoinPermissionOwnerAliyunId":"some-user2", "JoinPermissionId":"123456", "JoinPermissionType":"LOCAL", "DataDispatchEnabled":true, "FreqBandPlanGroupId":102, "NodeGroupName":"节点分组名称2", "TxDailySum":0, "TxMonthSum":0, "CreateMillis":1514736000000, "RxMonthSum":0 }, { "DataDispatchConfig":{ "IotProduct":{ "ProductKey":"xxxxxxxx",

828 文档版本:20200417

Page 841: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

"ProductType":"IOT_SUITE", "ProductName":"产品名" }, "Destination":"IOT" }, "NodeGroupId":"1234569", "NodesCnt":10, "Locks":[ { "LockId":"123", "Enabled":true, "LockSmithPlatformSource":"LP", "LockSmith":"nmsUser1", "CreateMillis":1514736000000, "LockType":"WRITE" }, { "LockId":"126", "Enabled":true, "LockSmithPlatformSource":"LP", "LockSmith":"nmsUser1", "CreateMillis":1514736000000, "LockType":"WRITE" } ], "RxDailySum":0, "JoinEui":"0000000000000001", "ClassMode":"A", "JoinPermissionEnabled":true, "JoinPermissionOwnerAliyunId":"some-user2", "JoinPermissionId":"1234569", "JoinPermissionType":"LOCAL", "DataDispatchEnabled":true, "FreqBandPlanGroupId":102, "NodeGroupName":"节点分组名称2", "TxDailySum":0, "TxMonthSum":0, "CreateMillis":1514736000000, "RxMonthSum":0 } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 829

Page 842: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

4.1.1.9.9 GetNodeGroup调用GetNodeGroup根据节点分组ID获取节点分组信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetNodeGroup 系统规定参数。取值:GetNodeGro

up。

NodeGroupId String 是 123456 节点分组ID。

返回数据

名称 类型 示例值 描述

Data 节点分组信息列表。

ClassMode String A 节点分组中的节点所采用的LoRaWAN

Class模式,与分组所关联的入网凭证中指

定的一致。

CreateMillis Long 1514736000000 节点分组的创建时间,格式为 UNIX 时间

戳,以毫秒为单位。

DataDispatchConfig

- - 节点分组的数据流转配置。

Destination String IOT 数据流转目的地。取值为IOT:数据流转

到 IoT 的产品。

IotProduct 如果流转目的地是IoT产品,该字段存储产

品信息。

ProductKey String xxxxxxxx 产品Product Key。

830 文档版本:20200417

Page 843: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

ProductName String 产品名 产品名。

ProductType String IOT_SUITE 产品类型。取值:

• IOT_SUITE:数据流转到IoT套件基础版。

• IOT_SUITE_SENIOR:数据流转到IoT套件高级版。

OnsTopics 如果流转目的地是MQ, 该字段存储MQ

Topic信息。

DownlinkRegionName

String cn-beijing MQ下行Region ID。

DownlinkTopic

String topic1 MQ下行Topic。

UplinkRegionName

String cn-hangzhou MQ上行Region ID。

UplinkTopic String topic2 MQ上行Topic。

DataDispatchEnabled

Boolean false 节点分组的数据流转启停状态,true表示

启用,false表示停用。

FreqBandPlanGroupId

Long 102 节点分组中的节点所采用的频段的频段

ID,与分组所关联的入网凭证中指定的一

致。

JoinEui String 0000000000000000

节点分组中的节点所使用的JoinEUI,与分

组所关联的入网凭证中指定的JoinEUI一

致。

JoinPermissionEnabled

Boolean true 与节点分组关联的入网凭证的启停状态,

true表示启用,false表示停用。

JoinPermissionId

String 1234569 与节点分组关联的入网凭证的ID。

JoinPermissionName

String 凭证1 与节点分组关联的入网凭证的名称。

文档版本:20200417 831

Page 844: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

JoinPermissionOwnerAliyunId

String some-user • 如果关联的是专用入网凭证,该字段表示入网凭证的拥有者的阿里云账号ID。

• 如果关联的是泛在入网凭证,该字段的值恒为AliCloud IoT。

JoinPermissionType

String LOCAL 与节点分组关联的入网凭证类型。取值:

• LOCAL:专用凭证• ROAMING:泛在凭证

Locks 节点分组所关联的操作锁列表。

CreateMillis Long 1514736000000 锁的创建时间。

Enabled Boolean true 锁的启停用状态。

LockId String 123 锁ID。

LockType String WRITE 锁的类型。取值:WRITE,所有写操作都

加锁,包括编辑、删除等。

NodeGroupId String 123456 节点分组ID。

NodeGroupName

String 节点分组名称 节点分组的名称。

NodesCnt Long 10 节点分组中的节点数量。

RxDailySum String 0 与节点分组关联的入网凭证的当天上行数

据包量。

RxMonthSum Long 0 与节点分组关联的入网凭证的当月上行数

据包量。

TxDailySum Long 0 与节点分组关联的入网凭证的当天下行数

据包量。

TxMonthSum Long 0 与节点分组关联的入网凭证的当月下行数

据包量。

832 文档版本:20200417

Page 845: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetNodeGroup&NodeGroupId=123456&<公共请求参数>

正常返回示例

XML 格式

<GetNodeGroupResponse> <Data> <NodesCnt>10</NodesCnt> <JoinEui>0000000000000000</JoinEui> <JoinPermissionOwnerAliyunId>some-user</JoinPermissionOwnerAliyunId> <RxDailySum>0</RxDailySum> <JoinPermissionType>LOCAL</JoinPermissionType> <ClassMode>A</ClassMode> <NodeGroupId>123456</NodeGroupId> <DataDispatchEnabled>true</DataDispatchEnabled> <Locks> <Lock> <LockId>123</LockId> <CreateMillis>1514736000000</CreateMillis> <Enabled>true</Enabled> <LockType>WRITE</LockType> </Lock> <Lock> <LockId>126</LockId> <CreateMillis>1514736000000</CreateMillis> <Enabled>true</Enabled> <LockType>WRITE</LockType> </Lock> </Locks> <JoinPermissionEnabled>true</JoinPermissionEnabled> <TxDailySum>0</TxDailySum> <TxMonthSum>0</TxMonthSum> <DataDispatchConfig> <Destination>IOT</Destination> <IotProduct> <ProductKey>xxxxxxxx</ProductKey> <ProductType>IOT_SUITE</ProductType> <ProductName>产品名</ProductName> </IotProduct> </DataDispatchConfig> <CreateMillis>1514736000000</CreateMillis> <NodeGroupName>节点分组名称</NodeGroupName> <RxMonthSum>0</RxMonthSum>

文档版本:20200417 833

Page 846: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<JoinPermissionId>1234569</JoinPermissionId> <FreqBandPlanGroupId>102</FreqBandPlanGroupId> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetNodeGroupResponse>

JSON 格式

{ "Data":{ "DataDispatchConfig":{ "IotProduct":{ "ProductKey":"xxxxxxxx", "ProductType":"IOT_SUITE", "ProductName":"产品名" }, "Destination":"IOT" }, "NodeGroupId":"123456", "NodesCnt":10, "Locks":[ { "LockId":"123", "Enabled":true, "CreateMillis":1514736000000, "LockType":"WRITE" }, { "LockId":"126", "Enabled":true, "CreateMillis":1514736000000, "LockType":"WRITE" } ], "RxDailySum":0, "JoinEui":"0000000000000000", "ClassMode":"A", "JoinPermissionEnabled":true, "JoinPermissionOwnerAliyunId":"some-user", "JoinPermissionId":"1234569", "JoinPermissionType":"LOCAL", "DataDispatchEnabled":true, "FreqBandPlanGroupId":102, "NodeGroupName":"节点分组名称", "TxDailySum":0, "TxMonthSum":0, "CreateMillis":1514736000000, "RxMonthSum":0 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

834 文档版本:20200417

Page 847: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.9.10 GetNode调用GetNode获取节点信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetNode 系统规定参数。取值:GetNode。

DevEui String 是 0000000000000000

节点的DevEUI。

返回数据

名称 类型 示例值 描述

Data 节点信息列表。

AuthTypes STANDARD 网关合约类型。

• HYBRID:hybrid网关• SINGLE_CHANNEL:单通道网关• STANDARD:标准合约网关

BoundMillis Long 1514736000000 节点加入当前节点分组的时间,UNIX时间

戳,以毫秒为单位。

文档版本:20200417 835

Page 848: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

ClassMode String A 节点所采用的LoRaWAN Class模式,可取

值:A、B、C。

DevAddr String 12345678 节点的网络地址。

DevEui String 0000000000000000

节点的DevEUI。

LastJoinMillis Long 1514736000000 最近一次入网的时间,UNIX时间戳,以毫

秒为单位。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetNode&DevEui=0000000000000000&<公共请求参数>

正常返回示例

XML 格式

<GetNodeResponse> <Data> <ClassMode>A</ClassMode> <BoundMillis>1514736000000</BoundMillis> <LastJoinMillis>1514736000000</LastJoinMillis> <DevEui>0000000000000000</DevEui> <DevAddr>12345678</DevAddr> </Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></GetNodeResponse>

JSON 格式

{ "Data":{ "DevEui":"0000000000000000", "ClassMode":"A", "BoundMillis":1514736000000, "DevAddr":"12345678", "LastJoinMillis":1514736000000

836 文档版本:20200417

Page 849: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.9.11 DeleteNodeGroup调用DeleteNodeGroup删除节点分组。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 DeleteNodeGroup

系统规定参数。取值:DeleteNode

Group。

NodeGroupId String 是 123456 要删除的节点分组ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

文档版本:20200417 837

Page 850: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

示例

请求示例

http://POP网关域名/?Action=DeleteNodeGroup&NodeGroupId=123456&<公共请求参数>

正常返回示例

XML 格式

<DeleteNodeGroupResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></DeleteNodeGroupResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

400 NodeGroupAlreadyBoundJoinPermission

This node group is already bound to a join permission.

节点组已经绑定入网凭证

838 文档版本:20200417

Page 851: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.9.12 CreateNodeGroup调用CreateNodeGroup创建节点分组。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CreateNodeGroup

系统规定参数。取值:CreateNode

Group。

NodeGroupName

String 是 group1 节点分组的名称。

JoinPermissionId

String 否 123 与节点分组关联的入网凭证ID。

返回数据

名称 类型 示例值 描述

Data String 123456 节点分组ID。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CreateNodeGroup&NodeGroupName=group1&<公共请求参数>

正常返回示例

XML 格式

<CreateNodeGroupResponse> <Data>123456</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CreateNodeGroupResponse>

JSON 格式

{ "Data":"123456",

文档版本:20200417 839

Page 852: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

"RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NodeGroupNameDuplicated

The specified node group name already exists.

节点组名称重复

400 NodeGroupAlreadyBoundJoinPermission

This node group is already bound to a join permission.

节点组已经绑定入网凭证

400 JoinPermissionDoesNotExist

The specified join permission does not exist.

入网凭证不存在

400 JoinPermissionAlreadyBoundNodeGroup

The specified join permission has already been bound to another node group.

入网凭证已经绑定了节点组

400 InvalidName The specified name is invalid.

名称不合法

4.1.1.9.13 CountNodesByOwnedJoinPermissionId调用CountNodesByOwnedJoinPermissionId统计使用某入网凭证且满足过滤条件的节点的数量。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountNodesByOwnedJoinPermissionId

系统规定参数。取值:CountNodes

ByOwnedJoinPermissionId。

JoinPermissionId

String 是 123 入网凭证ID。

FuzzyDevEui String 否 0000000000000000

模糊匹配节点的DevEUI。

840 文档版本:20200417

Page 853: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

Data Long 100 满足过滤条件的节点数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CountNodesByOwnedJoinPermissionId&JoinPermissionId=123&<公共请求参数>

正常返回示例

XML 格式

<CountNodesByOwnedJoinPermissionIdResponse> <Data>100</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CountNodesByOwnedJoinPermissionIdResponse>

JSON 格式

{ "Data":100, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 841

Page 854: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.9.14 CountNodesByNodeGroupId调用CountNodesByNodeGroupId统计某节点分组中且满足过滤条件的节点数量。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountNodesByNodeGroupId

系统规定参数。取值:CountNodes

ByNodeGroupId。

NodeGroupId String 是 123 节点分组ID。

FuzzyDevEui String 否 0000000000000000

模糊匹配节点的DevEUI。

返回数据

名称 类型 示例值 描述

Data Long 100 满足过滤条件的节点数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

正常返回示例

XML 格式

<CountNodesByNodeGroupIdResponse> <Data>100</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CountNodesByNodeGroupIdResponse>

JSON 格式

{ "Data":100, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true

842 文档版本:20200417

Page 855: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.9.15 CountNodeGroups调用CountNodeGroups统计符合过滤条件的节点分组总数。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountNodeGroups

系统规定参数。取值:CountNodeG

roups。

FuzzyDevEui String 否 d896e0 模糊匹配节点分组中节点的 DevEUI

FuzzyJoinEui String 否 d896e0 模糊匹配节点分组中节点所使用的

JoinEUI。

FuzzyName String 否 group1 模糊匹配节点分组名称。

返回数据

名称 类型 示例值 描述

Data Long 100 满足过滤条件的节点分组总数。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

文档版本:20200417 843

Page 856: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

示例

请求示例

http://POP网关域名/?Action=CountNodeGroups&<公共请求参数>

正常返回示例

XML 格式

<CountNodeGroupsResponse> <Data>100</Data> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></CountNodeGroupsResponse>

JSON 格式

{ "Data":100, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.9.16 BindJoinPermissionToNodeGroup调用BindJoinPermissionToNodeGroup建立入网凭证和节点分组的关联。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 BindJoinPermissionToNodeGroup

系统规定参数。取值:BindJoinPe

rmissionToNodeGroup。

JoinPermissionId

String 是 123456 参与关联的入网凭证ID。

844 文档版本:20200417

Page 857: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 是否必选 示例值 描述

NodeGroupId String 是 123 参与关联的节点分组ID。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

正常返回示例

XML 格式

<BindJoinPermissionToNodeGroupResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></BindJoinPermissionToNodeGroupResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 JoinPermissionDoesNotExist

The specified join permission does not exist.

入网凭证不存在

文档版本:20200417 845

Page 858: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 JoinPermissionAlreadyBoundNodeGroup

The specified join permission has already been bound to another node group.

入网凭证已经绑定了节点组

400 NodeGroupDoesNotExist

The specified node group does not exist.

节点组不存在

400 NodeGroupAlreadyBoundJoinPermission

This node group is already bound to a join permission.

节点组已经绑定入网凭证

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

4.1.1.9.17 UpdateNodeGroup调用UpdateNodeGroup更新节点分组。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 UpdateNodeGroup

系统规定参数。取值:UpdateNode

Group。

NodeGroupId String 是 123456 节点分组ID。

NodeGroupName

String 是 group1 节点分组的名称。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=UpdateNodeGroup

846 文档版本:20200417

Page 859: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&NodeGroupId=123456&NodeGroupName=group1&<公共请求参数>

正常返回示例

XML 格式

<UpdateNodeGroupResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></UpdateNodeGroupResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

400 NodeGroupNameDuplicated

The specified node group name already exists.

节点组名称重复

400 InvalidName The specified name is invalid.

名称不合法

400 ResourceLocked The specified resource has been locked by another product.

资源被其他云产品锁定

文档版本:20200417 847

Page 860: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.10 上下行数据

4.1.1.10.1 SendUnicastCommand调用SendUnicastCommand发送单播信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 SendUnicastCommand

系统规定参数。取值:SendUnicas

tCommand。

Content String 是 xxx 要发送的内容。

DevEui String 是 0000000000000000

目标节点。

FPort Integer 是 0 fPort。

CleanUp Boolean 否 false 是否清空该节点的堆积指令,并下发

该指令。默认为false。

Confirmed Boolean 否 false 是否是confirmed指令,默认为false

MaxRetries Integer 否 0 最大重发次数,默认为0。

返回数据

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=SendUnicastCommand&Content=xxx&DevEui=0000000000000000&FPort=0

848 文档版本:20200417

Page 861: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&<公共请求参数>

正常返回示例

XML 格式

<SendUnicastCommandResponse> <RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId> <Success>true</Success></SendUnicastCommandResponse>

JSON 格式

{ "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 Abandoned An error occurred while processing this request, because the API has been abandoned.

该接口已经被废弃。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

4.1.1.11 密钥管理

文档版本:20200417 849

Page 862: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.11.1 CountGatewayTupleOrders统计当前用户账号已提交的网关安全密钥工单的数量,可指定统计特定状态的工单。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountGatewayTupleOrders

系统规定参数。取值:CountGatew

ayTupleOrders。

States.N RepeatList否 APPLYING 工单状态过滤列表。若不使用此参

数,则表示统计所有状态的工单。

参考工单状态取值

类型说明

工单状态取值

名称 类型 说明

APPLYING String 申请中。

ACCEPTING String 颁发中。

ACCEPTED String 颁发成功。

ACCEPTING_FAILED String 颁发失败。

REJECTED String 已拒绝。

REVOKING String 撤回中。

REVOKING_FAILED String 撤回失败。

REVOKED String 撤回成功。

返回数据

名称 类型 示例值 描述

Data Long 42 满足状态过滤条件的工单数量。

850 文档版本:20200417

Page 863: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CountGatewayTupleOrders&<公共请求参数>

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data>42</Data>

JSON 格式

{ "Data":42, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

文档版本:20200417 851

Page 864: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.11.2 CountNodeTupleOrders统计当前用户账号所提交的节点安全密钥工单数量,可指定统计特定类型及特定状态的工单。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 CountNodeTupleOrders

系统规定参数。取值:CountNodeT

upleOrders。

IsKpm Boolean 否 true 类型过滤,是否是安全产线发起的工

单。

States.N RepeatList否 ACCEPTED 工单状态过滤列表。若不使用此参

数,则表示统计所有状态的工单。

参考工单状态取值

类型说明

工单状态取值

名称 类型 说明

APPLYING String 申请中。

ACCEPTING String 颁发中。

ACCEPTED String 颁发成功。

ACCEPTING_FAILED String 颁发失败。

REJECTED String 已拒绝。

REVOKING String 撤回中。

REVOKING_FAILED String 撤回失败。

REVOKED String 撤回成功。

852 文档版本:20200417

Page 865: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

Data Long 42 满足过滤条件的工单数量。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=CountNodeTupleOrders&State.1=APPLYING&State.2=ACCEPTING&IsKpm=false&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data>42</Data>

JSON 格式

{ "Data":42, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

文档版本:20200417 853

Page 866: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

4.1.1.11.3 GetGatewayTupleOrder获取网关安全密钥工单的信息,传入工单 ID,返回此工单的处理状态等信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetGatewayTupleOrder

系统规定参数。取值:GetGateway

TupleOrder。

OrderId String 是 1234 工单 Id。

返回数据

名称 类型 示例值 描述

Data 网关安全密钥工单信息。

AcceptedMillis Long 1514822400000 工单审批通过的 UNIX 时间戳,以毫秒为

单位。

CreatedMillis Long 1514736000000 提交此工单的 UNIX 时间戳,以毫秒为单

位。

OrderId String 1234 工单 Id。

OrderState String ACCEPTED 工单的状态。

参考工单状态取值

RequiredCount

Long 10 工单申请的网关安全密钥数量。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

854 文档版本:20200417

Page 867: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

示例

请求示例

http://POP网关域名/?Action=GetGatewayTupleOrder&OrderId=1234&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data> <OrderId>1234</OrderId> <OrderState>ACCEPTED</OrderState> <RequiredCount>1</RequiredCount> <CreatedMillis>1514736000000</CreatedMillis> <AcceptedMillis>1514822400000</AcceptedMillis></Data>

JSON 格式

{ "Data":{ "OrderState":"ACCEPTED", "CreatedMillis":1514736000000, "OrderId":1234, "AcceptedMillis":1514822400000, "RequiredCount":1 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

类型说明

工单状态取值

名称 类型 说明

APPLYING String 申请中。

REJECTED String 已拒绝。

ACCEPTING String 颁发中。

ACCEPTING_FAILED String 颁发失败。

ACCEPTED String 颁发成功。

文档版本:20200417 855

Page 868: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 说明

REVOKING String 撤回中。

REVOKING_FAILED String 撤回失败。

REVOKED String 撤回成功。

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.11.4 GetGatewayTuplesDownloadUrl网关安全密钥工单审批通过后,调用此接口可以获取一个下载链接,该链接指向一个 CSV 文件,其

中存储了颁发给该用户的网关安全密钥。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetGatewayTuplesDownloadUrl

系统规定参数。取值:GetGateway

TuplesDownloadUrl。

OrderId String 是 1234 工单 ID。

856 文档版本:20200417

Page 869: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

返回数据

名称 类型 示例值 描述

Data String http://xxx.xxx/xxx.csv

网关安全元组文件下载链接。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetGatewayTuplesDownloadUrl&OrderId=1234&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data>http://xxx.xxx/xxx.csv</Data>

JSON 格式

{ "Data":"http://xxx.xxx/xxx.csv", "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

文档版本:20200417 857

Page 870: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

400 GatewayTupleOrderNotAccepted

The order on gateway tuple downloading is not approved. You cannot download the gateway tuple.

网关元组工单没有审批通过,无法下载网关元组。

4.1.1.11.5 GetNodeTupleOrder获取节点安全密钥工单信息,传入工单 ID,返回此工单的处理状态等信息。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetNodeTupleOrder

系统规定参数。取值:GetNodeTup

leOrder。

OrderId String 是 1234 工单 ID。

返回数据

名称 类型 示例值 描述

Data 节点安全元组工单信息。

AcceptedMillis Long 1514822400000 工单审批通过的 UNIX 时间戳,以毫秒为

单位。

CreatedMillis Long 1514736000000 提交工单的 UNIX 时间戳,以毫秒为单

位。

IsKpm Boolean false 是否是安全产线发起的密钥申请。

858 文档版本:20200417

Page 871: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

OrderId String 1234 工单 ID。

OrderState String ACCEPTED 工单状态。

审批状态取值

APPLYING申请中。

ACCEPTING颁发中。

ACCEPTED颁发成功。

ACCEPTING_FAILED颁发失败。

REJECTED已拒绝。

REVOKING撤回中。

REVOKING_FAILED撤回失败。

REVOKED撤回成功。

RequiredCount

Long 10 工单申请的节点安全密钥数量。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetNodeTupleOrder&OrderId=12345&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data> <OrderId>1234</OrderId> <IsKpm>false</IsKpm> <OrderState>ACCEPTED</OrderState>

文档版本:20200417 859

Page 872: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<RequiredCount>1</RequiredCount> <CreatedMillis>1514736000000</CreatedMillis> <AcceptedMillis>1514822400000</AcceptedMillis></Data>

JSON 格式

{ "Data":{ "OrderState":"ACCEPTED", "CreatedMillis":1514736000000, "OrderId":1234, "IsKpm":false, "AcceptedMillis":1514822400000, "RequiredCount":1 }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

类型说明

审批状态取值

名称 类型 说明

APPLYING String 申请中。

ACCEPTING String 颁发中。

ACCEPTED String 颁发成功。

ACCEPTING_FAILED String 颁发失败。

REJECTED String 已拒绝。

REVOKING String 撤回中。

REVOKING_FAILED String 撤回失败。

REVOKED String 撤回成功。

860 文档版本:20200417

Page 873: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

4.1.1.11.6 GetNodeTuplesDownloadUrl节点安全密钥工单审批通过后,调用此接口可以获取一个下载链接,该链接指向一个 CSV 文件,其

中存储了颁发给该用户的节点安全密钥。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 GetNodeTuplesDownloadUrl

系统规定参数。取值:GetNodeTup

lesDownloadUrl。

OrderId String 是 1234 工单 ID。

返回数据

名称 类型 示例值 描述

Data String http://xxx.xxx/xxx.csv

节点安全密钥文件下载链接。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

文档版本:20200417 861

Page 874: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=GetNodeTuplesDownloadUrl&OrderId=1234&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data>http://xxx.xxx/xxx.csv</Data>

JSON 格式

{ "Data":"http://xxx.xxx/xxx.csv", "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 NonExistent The specified resource does not exist.

要操作的资源不存在。

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 NotResourceOwner

You are not authorized to use this resource.

无权访问此资源

862 文档版本:20200417

Page 875: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.11.7 ListGatewayTupleOrders获取用户已提交的网关元组工单列表。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListGatewayTupleOrders

系统规定参数。取值:ListGatewa

yTupleOrders。

Limit Long 是 10 本次查询的工单数量上限,大于等于

1。

Offset Long 是 0 本次查询的起始位置,从 0 开始。

Ascending Boolean 否 true 配合 SortingField 参数一起使用,

true 表示升序,false 表示降序

SortingField String 否 CREATED_MILLIS 查询结果排序字段:

可取值为 CREATED_MILLIS(根据工

单发起时间排序),

ACCEPTED_MILLIS(根据工单审批通

过时间排序)。

State.N RepeatList否 APPLYING 工单状态过滤列表,若不使用此参

数,则表示查询所有状态的工单

参考工单状态取值

类型说明

工单状态取值

名称 类型 说明

APPLYING String 申请中。

REJECTED String 已拒绝。

ACCEPTING String 颁发中。

文档版本:20200417 863

Page 876: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 说明

ACCEPTING_FAILED String 颁发失败。

ACCEPTED String 颁发成功。

REVOKING String 撤回中。

REVOKING_FAILED String 撤回失败。

REVOKED String 撤回成功。

返回数据

名称 类型 示例值 描述

Data 返回的结果。

List 查询到的网关密钥工单信息列表。

AcceptedMillis Long 1514822400000 工单审批通过的 UNIX 时间戳,以毫秒为

单位。

CreatedMillis Long 1514736000000 提交此工单的 UNIX 时间戳,以毫秒为单

位。

OrderId String 1234 网关密钥订单编号。

OrderState String ACCEPTED 网关密钥申请状态。

RequiredCount

Long 2 网关密钥颁发数量。

TupleType String standard 网关密钥类型

低速版(单通道型):singlechannel

标准版:standard

高速版(Hybrid型):hybrid

高速版:noncontractual

864 文档版本:20200417

Page 877: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

TotalCount Long 42 满足过滤条件的订单总数量。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListGatewayTupleOrders&SortingField=CREATED_MILLIS&State.1=ACCEPTED&State.2=REJECTED&Ascending=false&Limit=2&Offset=0&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data> <TotalCount>42</TotalCount> <List> <OrderId>1234</OrderId> <OrderState>ACCEPTED</OrderState> <RequiredCount>1</RequiredCount> <CreatedMillis>1514736000000</CreatedMillis> <AcceptedMillis>1514822400000</AcceptedMillis> <TupleType>noncontractual</TupleType> </List> <List> <OrderId>1235</OrderId> <OrderState>ACCEPTED</OrderState> <RequiredCount>1</RequiredCount> <CreatedMillis>1514736000000</CreatedMillis> <AcceptedMillis>1514822400000</AcceptedMillis> <TupleType>noncontractual</TupleType> </List></Data>

JSON 格式

{ "Data":{ "TotalCount":42, "List":[

文档版本:20200417 865

Page 878: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

{ "OrderState":"ACCEPTED", "CreatedMillis":1514736000000, "OrderId":1234, "AcceptedMillis":1514822400000, "RequiredCount":1, "TupleType":"noncontractual" }, { "OrderState":"ACCEPTED", "CreatedMillis":1514736000000, "OrderId":1235, "AcceptedMillis":1514822400000, "RequiredCount":1, "TupleType":"noncontractual" } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

866 文档版本:20200417

Page 879: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.11.8 ListNodeTupleOrders获取用户已提交的节点密钥工单列表。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 ListNodeTupleOrders

系统规定参数。取值:ListNodeTu

pleOrders。

Limit Long 是 10 本次查询的工单数量上限,大于等于

1。

Offset Long 是 0 本次查询的起始位置,从 0 开始。

Ascending Boolean 否 true 配合 SortingField 参数一起使用,

true 表示升序,false 表示降序。

IsKpm Boolean 否 true 是否是 kpm 发起的工单。

SortingField String 否 CREATED_MILLIS 查询结果排序字段,可取值为

CREATED_MILLIS(根据工单发起时间

排序), ACCEPTED_MILLIS(根据工单

审批通过时间排序)。

State.N RepeatList否 APPLYING 工单状态过滤,如未传入此参数,则

不限制工单状态。

参考工单状态取值

类型说明

工单状态取值

名称 类型 说明

APPLYING String 申请中。

REJECTED String 已拒绝。

ACCEPTING String 颁发中。

文档版本:20200417 867

Page 880: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 说明

ACCEPTING_FAILED String 颁发失败。

ACCEPTED String 颁发成功。

REVOKING String 撤回中。

REVOKING_FAILED String 撤回失败。

REVOKED String 撤回成功。

返回数据

名称 类型 示例值 描述

Data - 返回的结果。

List - 满足过滤条件的节点元组工单信息列表。

AcceptedMillis Long 1514822400000 工单审批通过的 UNIX 时间戳,以毫秒为

单位。

CreatedMillis Long 1514736000000 提交此工单的 UNIX 时间戳,以毫秒为单

位。

FailedCount Long 0 节点颁发失败数。

IsKpm Boolean false 是否是 kpm 发起的工单。

LoraVersion String 1.0.2 LoRaWAN协议版本。

OrderId String 1234 工单编号。

OrderState String ACCEPTED 节点密钥申请状态。

RequiredCount

Long 1 节点密钥申请数量。

SuccessCount Long 1 节点密钥颁发数量。

TupleType String noncontractual 节点密钥类型

868 文档版本:20200417

Page 881: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

名称 类型 示例值 描述

TotalCount Long 42 满足过滤条件的工单数量

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=ListNodeTupleOrders&SortingField=CREATED_MILLIS&State.1=ACCEPTED&State.2=REJECTED&Ascending=false&Limit=2&Offset=0&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data> <TotalCount>42</TotalCount> <List> <OrderId>1234</OrderId> <IsKpm>false</IsKpm> <OrderState>ACCEPTED</OrderState> <RequiredCount>1</RequiredCount> <SuccessCount>1</SuccessCount> <FailedCount>0</FailedCount> <LoraVersion>1.0.2</LoraVersion> <CREATEDMillis>1514736000000</CREATEDMillis> <AcceptedMillis>1514822400000</AcceptedMillis> <TupleType>noncontractual</TupleType> </List> <List> <OrderId>1235</OrderId> <IsKpm>false</IsKpm> <OrderState>REJECTED</OrderState> <RequiredCount>1</RequiredCount> <SuccessCount>1</SuccessCount> <FailedCount>0</FailedCount> <LoraVersion>1.0.2</LoraVersion> <CREATEDMillis>1514736000000</CREATEDMillis> <AcceptedMillis>1514822400000</AcceptedMillis> <TupleType>noncontractual</TupleType> </List>

文档版本:20200417 869

Page 882: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

</Data>

JSON 格式

{ "Data":{ "TotalCount":42, "List":[ { "CREATEDMillis":1514736000000, "OrderState":"ACCEPTED", "FailedCount":0, "SuccessCount":1, "OrderId":1234, "LoraVersion":"1.0.2", "IsKpm":false, "AcceptedMillis":1514822400000, "RequiredCount":1, "TupleType":"noncontractual" }, { "CREATEDMillis":1514736000000, "OrderState":"REJECTED", "FailedCount":0, "SuccessCount":1, "OrderId":1235, "LoraVersion":"1.0.2", "IsKpm":false, "AcceptedMillis":1514822400000, "RequiredCount":1, "TupleType":"noncontractual" } ] }, "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

870 文档版本:20200417

Page 883: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

HttpCode 错误码 错误信息 描述

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

4.1.1.11.9 SubmitNodeTupleOrder提交节点密钥申请工单。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 SubmitNodeTupleOrder

系统规定参数。取值:SubmitNode

TupleOrder。

LoraVersion String 是 1.0.2 LoRaWAN协议版本。

RequiredCount Long 是 10 要申请的节点密钥数量。

TupleType String 否 standard 申请的秘钥类型

noncontractual:专业版密钥

standard:标准版密钥

relay:中继密钥

返回数据

名称 类型 示例值 描述

Data String 12345 工单 Id。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=SubmitNodeTupleOrder

文档版本:20200417 871

Page 884: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

&LoraVersion=1.0.2&RequiredCount=10&<公共请求参数>

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId><Success>true</Success><Data>12345</Data>

JSON 格式

{ "Data":"12345", "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

872 文档版本:20200417

Page 885: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

4.1.1.11.10 SubmitGatewayTupleOrder提交网关密钥申请工单。

请求参数

名称 类型 是否必选 示例值 描述

Action String 是 SubmitGatewayTupleOrder

系统规定参数。取值:SubmitGate

wayTupleOrder。

RequiredCount Long 是 2 要申请的网关安全密钥的数量。

TupleType String 否 noncontractual 网关密钥类型

低速版(单通道型):singlechannel

标准版:standard

高速版(Hybrid型):hybrid

高速版:noncontractual

返回数据

名称 类型 示例值 描述

Data String 12345 工单id。

RequestId String 89EF6CAA-958F-F32C-BE45-FE003C6DE097

请求ID。

Success Boolean true 是否成功。

示例

请求示例

http://POP网关域名/?Action=SubmitGatewayTupleOrder&RequiredCount=10&TupleType=standard&公共参数

正常返回示例

XML 格式

<RequestId>89EF6CAA-958F-F32C-BE45-FE003C6DE097</RequestId>

文档版本:20200417 873

Page 886: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

<Success>true</Success><Data>12345</Data>

JSON 格式

{ "Data":"12345", "RequestId":"89EF6CAA-958F-F32C-BE45-FE003C6DE097", "Success":true}

错误码

HttpCode 错误码 错误信息 描述

400 ForbiddenByRam User not authorized to operate on the specified resource, or this API does not support RAM.

用户没有执行该操作所需要的RAM权限。

400 ForbiddenByRiskControl

This operation cannot be performed because of security risks.

存在安全风险,无法执行该操作

400 InternalError The request processing has failed due to some unknown error, exception or failure.

内部错误。

400 CloudProductNotActivated

The Link WAN service has not been activated.

未开通 Link WAN 云产品

400 FeatureNotActivated

The feature has not been activated.

功能未开通

400 ExceedGatewayTupleLimit

The maximum number of gateway tuples is exceeded.

超出网关元组限额

4.1.2 云端SDK参考

4.1.2.1 Java SDK使用说明物联网络管理平台提供Java SDK,方便开发者使用Java程序操作物联网络管理平台。开发者可以使

用Maven依赖添加SDK。

1. 安装 Java 开发环境。

您可以从 Java 官方网站下载,并按说明安装Java开发环境。

874 文档版本:20200417

Page 887: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

2. 安装物联网络管理平台 Java SDK。

a. 访问 Apache Maven 官网下载 Maven 软件。

b. 添加 Maven 项目依赖。

物联网络管理平台 SDK 的 Maven 依赖坐标:

<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-linkwan</artifactId> <version>1.0.4</version></dependency>

阿里云云端公共 SDK 的 Maven 依赖坐标:

<dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.1.1</version></dependency>

初始化 SDK

初始化SDK,并实例化 IAcsCLient 接口。(即以下代码片段中的 client 对象)。

String regionId = "cn-shanghai";String accessKeyId = "< 您阿里云账号的 AccessKeyId, 支持子账号 >";String accessKeySecret = "< 您阿里云账号的 AccessKeySecret, 支持子账号 >";DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, accessKeySecret);IAcsClient client = new DefaultAcsClient(profile);

说明:

accessKeyId 即您阿里云账号的 AccessKey ID,accessKeySecret 即 AccessKey ID 对应的

AccessKey Secret。您可在阿里云官网控制台 AccessKey 管理中创建或查看您的 AccessKey。

发起调用

下文以调用 SendUnicastCommand API方法向节点下发业务数据为例,描述调用API的方法,即向

节点下发业务数据。

SendUnicastCommandRequest request = new SendUnicastCommandRequest();

request.setProtocol(ProtocolType.HTTPS);request.setMethod(MethodType.POST);//设备唯一身分标识DevEUIrequest.setDevEui("0000000000000000");//当前业务数据最大下发次数request.setMaxRetries(0);//设备对应端口号request.setFPort(0);//业务数据下发类型

文档版本:20200417 875

Page 888: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

request.setComfirmed(false);//是否清除之前的业务指令request.setCleanUp(false);//具体业务指令request.setContent("00000000");request.setProtocol(ProtocolType.HTTP);

try { SendUnicastCommandResponse response = client.getAcsResponse(request); System.out.println(response);} catch (ClientException e) { e.printStackTrace();}

4.2 设备端开发指南

4.2.1 获取网关SDK本文简单介绍了基于阿里提供的网关SDK进行网关设备快速接入,建立与Alibaba Cloud Link

WAN平台连接通道,目标为帮助网关设备厂商快速了解设备接入的流程。

下载代码

代码库提供稳定版的网关SDK。进入代码库可选择直接下载zip文件,或者在代码库中设置好SSH登录

方式获得代码。

说明:

SDK中modules/pktfwd是基于semtech官方的LoRaWAN协议栈,已增加了阿里修改的功

能patch,厂商可以根据自己平台需要合入相应代码到SDK中。

修改配置文件

make.settings为编译配置脚本文件,配置选项说明如下: 厂商根据自己本地的toolchain路

径、toolchain对应的host修改以下2个配置。

export __PATH__=\$(pwd)/toolchain/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09\_linux/bin:\$PATHexport __BUILDHOST__=arm-linux-gnueabihf

编译

./build.sh all

说明:

编译后生成的最终文件在out目录下。

876 文档版本:20200417

Page 889: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

配置网关三元组

auth\_key.json为网关三元组配置文件,厂商根据自己所申请到的网关三元组进行加密后修改相应配

置项。

说明:

网关三元组可在可在对应环境中申请取得。

运行

运行mqtt日志输出如下,表示网关上下行已联通。

mqtt.c-publish\_gwmp\_msg\_uplink:356__publish mqtt gwmp msg__mqtt.c-event\_handle:156__publish success__, packet-id=16checkCnt=1mqtt.c-callback\_gwmp\_msg\_downlink:469__received mqtt gwmp msg__mqtt.c-callback\_gwmp\_msg\_downlink:477__send gwmp msg__

架构总览

从底部到顶部,采用分层架构,包括:

• 硬件层:由厂商网关硬件提供。

• OS层:基于Linux系统。

• HAL层:SX1301/1308驱动(libloragw)。

• 上层:包括LoRaWAN协议栈packet_forwarder、IPC通讯、系统服务、系统应用。

文档版本:20200417 877

Page 890: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

目录结构

目录名称 内容描述

external SDK使用的第三方开源库,包括:cJSON、dbus、hiredis和libexpat

libraries 阿里所提供的库,包括:iotx-sdk-c和ipc-bus

modules LoRa网关功能模块,包括:mqtt和pktfwd

packages 预先编译的功能模块

make.settings SDK编译配置脚本

build.sh 编译SDK的命令脚本

docs SDK文档,包括:网关接入规范文档、 SDK使用手册;

README.md 编译说明

SDK使用说明

详情请参见SDK使用手册:docs/loragw\_sdk\_manual.pdf。

网关接入要求

详情请参见网关接入规范文档:docs/阿里云Link WAN网关接入规范.pdf。

4.2.2 获取节点SDKNode SDK是Alibaba Cloud Link WAN为合作伙伴(模组设备厂商)提供的LoRaWAN节点SDK, 在

完善和修复Semtech开源节点源码的缺陷基础之上,新增了额外的具有实用价值的新特性说明、参考

实现和应用实例,符合LinkWAN接入规范,能够帮助模组厂商缩短新特性的开发周期,扩大模组的应

用场景,提高市场竞争力。

下载代码

代码库提供稳定版的节点SDK。进入代码库,您可以选择直接下载zip文件,或者在代码库中设置

好SSH登录方式获得代码。

配置环境

• CMake 版本≥3.6

• GNU ARM-Toolchain

• (可选)Visual Studio Code

• SEGGER-JLink(烧录工具)

• 安装配置详见此处

878 文档版本:20200417

Page 891: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

修改编译配置

打开./LoRaMac-node/buildconfig.sh,配置您使用的开发板型号和工具链路径。 修改./LoRaMac

-node/src/LoRaModuleSDK/Commissioning.h 中节点三元组信息和组播地址和秘钥。

说明:

节点三元组取得方式:可在对应环境中申请取得,专业版与标准版密钥皆可使用。

编译

cd ./LoRaMac-nodesh build.sh

编译结果:

./build/src/apps/LoRaMac/SdkExample-LoRaWanModule.hex

效果

下载Hex文件到开发板(默认ST NucleoL476开发板)后退出,JLink 烧录方式如下: JLinkExe->

loadfile build/src/apps/LoRaMac/SdkExample-LoRaWanModule.hex 。

打开串口调试工具,重启运行显示输出结果如下。

**********************************************====== LinkWAN LoRa Node SDK Example =========== LoRaWAN 1.0.3 Specification,CN470 =====*********************************************

This is Debug Version, Input AT Cmd to start your Experience!

=======================================================****Set DevInfo: e.g. AT+CDEVEUI=devEui, AT+CAPPEUI=joinEUI,AT+CAPPKEY=appKey ****Start OTAA Join: e.g. AT+CJOIN=1,1****Send Data: e.g. AT+DTX=10,0123456789 ****Switch Class: e.g. AT+CCLASS=2 (classC) ****Switch Class: e.g. AT+CCLASS=1,0,2 (classB) ****Enter Repeater Mode: e.g. AT+CJOINMODE=1 ****ConfirmUp Send Periodically(20s): e.g. AT+CCONFIRM=1, AT+CRM=1,20 ****More AT Cmd infor, pls ref <ICA AT Cmd Spec>. =======================================================

文档版本:20200417 879

Page 892: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

调试

用JLINK和GDB调试开发板如下,以ST NucleoL476开发板为例: 开启JLinkGDBServer:

JLinkGDBServer -device STM32L476RGTx -if swd -speed 4000

开启GDB Client进行调试。

arm-none-eabi-gdb SdkExample-classB -ex "target remote localhost:2331"

技术架构图

SDK说明

请见SDK使用手册:./LoRaNodeSDK/Doc/NodeSDK_Manual_vX.X.X.pdf。

880 文档版本:20200417

Page 893: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

节点接入要求:请见接入规范文档:./LoRaNodeSDK/Doc/阿里云Link WAN节点接入规范vX.X.X.

pdf。

硬件支持

开发板

默认能运行LoRaWAN协议栈的开发板都支持,如:

• NucleoL073

• NucleoL152

• NucleoL476 (default)

• SAML21

• SKiM880B

• SKiM980A

• SKiM881AXL

硬件移植

可参考LoRaWAN Alliance移植文档。

版本发布

• v2.0.4 ChangeNotes

- 支持RAK811节点开发板;

- AT Cmd:增加使用说明打印,bugfix AT+CDEVADDR;

• v2.0.3 ChangeNotes: 主要包括以下功能和服务

- 提供了《LinkWAN节点接入规范》的全频段扫描参考实现。

- 提供了《ICA联盟标准-面向LoRa的AT指令集规范1.0》增强版的参考实现。

- 支持LinkWAN ClassA节点的中继模式。

- 支持LBT功能。

- 支持检测节点协议。

- 支持ABP模式。

文档版本:20200417 881

Page 894: 阿里云IoT Link Rack 一体机

开发指南 /  4 物联网络管理平台

• v2.0.2 ChangeNotes: 主要包括以下功能和服务

- 提供了认证模式功能。

- 对上层提供更便捷的应用API。

- 新增实现了联盟的应用层组播功能。

- 新增LoRa模块连接策略(入网退避策略,ClassB切换策略,时间同步策略等)。

- 对原有ClassA/B/C缺陷进行修复。

- 对现有LoRaWAN节点协议栈的鲁棒性、可靠性、稳定性做了进一步增强。参考链接如下:

■ LoRa Alliance协议规范。

■ ICA联盟标准规范。

■ LoRaWAN协议节点开源实现,详见LoRaNodeSDK/Doc/NodeSDK_QuickStart.docx。

882 文档版本:20200417

Page 895: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

5 物联网安全运营中心

5.1 设备接入物联网安全运营中心Link Security Operations Center(简称SOC)支持多种物联网设备操作系

统,为设备提供不同等级的保护。

在Android和Linux设备上,可以使用设备保护服务Device Protection Service(简称 DPS),实

时检测入侵,及时修复漏洞。在AliOS Things或其它RTOS设备上,可以使用设备取证服务Device

Attestation Service(简称 DAS),持续掌握设备的安全状况。

选择开发包

设备上启用DPS或DAS服务,要先选择和设备系统相应的SDK开发包。

设备端 版本号 发布时间 使用环境 版本说明

DAS 1.0.1 2018-12-25 RTOS • 上报运行状态• 定期检测系统完整性

DPS 1.1.2 (beta)

2019-07-19 Android 5/7/

8

(ARM/

ARM64)

• 上报运行状态• 定期检测系统完整性• 安全基线生成和管理• 漏洞检测/修复• 设备行为检测• 风险检测/处置• 安全运营托管

文档版本:20200417 883

Page 896: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

设备端 版本号 发布时间 使用环境 版本说明

DPS 1.1.2 (beta)

2019-07-20 Linux

(x64/ARM64

/ARMHF)

• 上报运行状态• 定期检测系统完整性• 安全基线生成和管理• 漏洞检测和修复• 设备行为检测• 风险检测和处置• 安全运营托管

注意:

• (beta)表示:未经充分测试验证存在未知风险。因此,beta版仅用于在实验环境测试或熟悉功

能用,禁止用于生产环境。

• 获取支持Docker环境的DPS,请联系阿里云技术人员。

集成开发

DPS/DAS运行时需要设备有上云通道和安全运营中心互动消息和控制,SDK中提供的DPS/DAS客户

端API使设备应用将原有上云通分享给DPS使用,无需另外建立网络连接。详细说明请参见后面两篇

SDK介绍文档。

DAS在适配AliOS Things之外的其它RTOS系统时,需要适配DAS中设备相关的基础功能函数。

安装配置

DPS本身是自包含服务,不需要额外的编译集成,并且有预置的上云通道。如果设备允许多个上云连

接存在,则可以选择直接使用DPS开发包进行安装。按照SDK介绍文档内容配置具体的服务参数和上

云参数后即可运行。

5.2 设备保护服务SDK

884 文档版本:20200417

Page 897: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

5.2.1 概览设备保护服务Device Protection Service(以下简称为 DPS), 是为Linux、Android等智能设备提

供的安全保护服务。DPS不仅可以提供实时的入侵检测,还负责及时修复安全问题,使设备受到持续

的安全防护。

下载SDK

版本号 发布日期 目标设备

DPS 1.1.2(beta) 2019-07-19 Android 5/7/8

(ARM/ARM64)

DPS 1.1.2(beta) 2019-07-20 Linux

(x64/ARM64/ARMHF)

注意:

(beta)表示:未经充分测试验证存在未知风险。因此,beta版仅用于在实验环境测试或熟悉功能

用,禁止用于生产环境。

5.2.2 Linux系统集成本章主要介绍在Linux系统上集成开发的操作。

开发环境

当前Linux X86-64 SDK需在有systemd为init的系统上开发。

开发包下载完成后,将其解压到目标设备开发环境所在机器上的任意目录。再根据目标设备开环境的

具体要求,将SDK目录引入到设备的开发环境中。

编译设置

DPS开发包提供标准的Makefile编译脚本,以适配一般Linux设备的编译环境。其中差异化的配置可

以在SDK包中的config.mk文件中指定。

• 硬件体系

ARCH := x86_64

DPS SDK目前支持Armhf,Arm64,x86_64三个目标平台架构。

文档版本:20200417 885

Page 898: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

• DPS_DATA

DPS_DATA := /data/dps

指定DPS的data目录,该目录主要用来存放基线规则,以及客户端在运行过程中产生的临时文件

等。

缺省值为/data/dps ,请确保/data目录或者相应分区可读、可写。

• DPS_PROFILE

DPS_PROFILE := standard

DPS类型,取值为standard、server、lite中的一种。当开发板的CPU性能较差时,可选择lite模

式。

缺失值为standard 。

• PROTECTED_PATH

PROTECTED_PATH := /home/dps/my_important_dir

scanner默认扫描常规系统目录。如果有用户需要自定义scanner额外的扫描路径,可在这里指

定。

• SYSTEM_VERSION

SYSTEM_VERSION := version://textfile:/etc/YOUR_VERNO_FILE:.+SYSTEM_VERSION := version://string:ver.1.0.0

若选择textfile比对方式,则指定厂商固件版本号寄存的文本文件路径,例如/etc/YOUR_VERNO

_FILE,按照定义的正则表达式从该文件路径中解析版本号,例如.+正则表达式。如果选

择string比对方式,那么直接使用接续字串当做固件版本号,例如ver.1.0.0。

• MANAGED_ID

MANAGED_ID := managedid://textfile:/etc/MANAGED_ID:.+MANAGED_ID := managedid://string:15709823

MANAGED_ID同SYSTEM_VERSION,也可选择字串和档案正则表达方式。

886 文档版本:20200417

Page 899: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

• 客户端选项

客户端主要用来连接云端,接收和发送云端指令。相关配置选项在SDK包的config.mk中指定。

DPS连云提供了两种方式,一种是直接使用SDK包里的dps_client客户端程序,可通过设备证书直

接上云;另一种是使用SDK包中提供的Makefile脚本编译libclient.a,然后将libclient.a集成到自

己的项目中,通过库导出的接口连接云端。

使用独立DPS客户端:

1. 打开相应开关。

CONFIGURE_STANDALONE_CLIENT := 1

说明:

配置CONFIGURE_STANDALONE_CLIENT为1,则使用SDK包中自带的独立DPS客户端,可通

过设备证书信息直接与云端建立连接。

2. 配置设备证书(ProductKey、DeviceName、DeviceSecret)。

PRODUCT_KEY := ProductKeyDEVICE_NAME := DeviceNameDEVICE_SECRET := DeviceSecret

说明:

当且仅当CONFIGURE_STANDALONE_CLIENT为1时,才需要配置设备证书,否则配置不生

效。

编译客户端开发库:

1. 打开相应开关。

CONFIGURE_CLIENT_LIBRARY := 1CONFIGURE_IOTX_LIBRARY := 0CONFIGURE_BUILD_CLIENT := 0

说明:

文档版本:20200417 887

Page 900: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

配置 CONFIGURE_CLIENT_LIBRARY 为1,则需要编译 DPS 客户端开发库 libclient.a ,供自

有客户端项目集成使用。

另外, CONFIGURE_IOTX_LIBRARY开关用来编译Linkkit开发库。该库主要用来最终编译演示

版dps_client客户端程序之用,用户在实际项目中自行替换成最新的Linkkit开发库即可。客户

端开发库libclient.a内部封装了Linkkit开发库导出的接口。

CONFIGURE_BUILD_CLIENT开关用来编译完整的演示版dps_client客户端程序,其主要功能

是用来演示如何将客户端开发库libclient.a集成进自有的客户端项目中。

2. 指定ToolChain安装路径。

目标平台toolchain安装路径在toolchains/config.mk文件中指定。

TOOLCHAIN_INSTL_DIR := $(HOME)/your_toolchain_path_dir

3. 编译libclient.a。

make libs

如果上述配置都没有问题,那么最终编译出来的库会在会放在output/lib_a/libclient.a。

最后,将编译出来的.a库集成到自己的工程中即可。

• 其他组件选项

CONFIGURE_SANDBOX_SERVICE := 0

DPS沙箱服务,主要用来限制进程的行为和权限,防止病毒作恶。具体使用方式参考DPS

Sandbox相关文档。

• 安装路径

SDK中Makefile的主要工作是将DPS各组件释放到目标image的rootfs根目录下,并自动创建相关

文件夹。

那么,上述所有配置完毕之后,就可以将DPS SDK解压并释放到指定的安装目录中了。安装目录

可以在SDK包的config.mk中指定。

prefix ?= /device_root_path

也可以在安装的时候通过参数形式指定。

make install prefix=/device_root_path

内核配置

开发者如果需要为目标设备编译Linux Kernel,请确保Linux Kernel版本在3.15及以上。并且需要检

查在Kernel编译的defconfig选项中使能了以下项目。

888 文档版本:20200417

Page 901: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

• 开启AUDIT和NETLINKE

CONFIG_AUDIT_ARCH=yCONFIG_AUDIT=yCONFIG_HAVE_ARCH_AUDITSYSCALL=yCONFIG_AUDITSYSCALL=yCONFIG_AUDIT_WATCH=yCONFIG_AUDIT_TREE=yCONFIG_NF_CT_NETLINK=yCONFIG_NF_CT_NETLINK_TIMEOUT=yCONFIG_NETFILTER_NETLINK_GLUE_CT=y

• 开启NETFILTER和IPTABLES

CONFIG_NETFILTER=yCONFIG_NETFILTER_NETLINK=yCONFIG_NETFILTER_NETLINK_ACCT=yCONFIG_NETFILTER_NETLINK_QUEUE=yCONFIG_NETFILTER_NETLINK_LOG=yCONFIG_IP_NF_IPTABLES=y

• 开启XTABLES及相关选项

CONFIG_NETFILTER_XTABLES=y

## Xtables combined modules#CONFIG_NETFILTER_XT_MARK=y...

## Xtables targets#CONFIG_NETFILTER_XT_TARGET_AUDIT=y...

## Xtables matches#CONFIG_NETFILTER_XT_MATCH_BPF=y...

编译示例

DPS模块提供头文件和静态库供设备应用集成使用。AppSample为实现参考。

• $(DPS_SDK)/client/inc/DPSClient.h

DPS client header file

• $(DPS_SDK)/output/lib_a/libdpsclient.a

DPS client static library

• $(DPS_SDK)/output/lib_a/libiotx.a

Link MQTT static library

文档版本:20200417 889

Page 902: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

应用Makefile示例:

CPPFLAGS += -I$(DPS_SDK)/client/incLDFLAGS += -L$(DPS_SDK)/output/libdpsclient.aLDFLAGS += -L$(DPS_SDK)/output/libiotx.a

启动设置

正常情况下,DPS SDK通过Makefile install预装入image。操作系统启动的过程中会将DPS SDK拉

起,无需额外配置。

systemd启动方式如下步骤所示。

1. 在编译目标系统Image之前,在目标系统的/usr/lib/systemd/system/目录下创建dpsd.service

文件。

[Unit]Description=dps deamon server# After=network.target

[Service]ExecStart=/system/dps/bin/dpsdType=simpleUser=rootGroup=rootKillMode=processRestart=alwaysRestartSec=10s

[Install]WantedBy=multi-user.targetAlias=dpsd.service

2. 在/etc/systemd/system/multi-user.target.wants/目录下创建软连接,指向/usr/lib/

systemd/system/dpsd.service文件。

890 文档版本:20200417

Page 903: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

5.2.3 Android系统集成本章主要介绍在Android系统上集成开发的操作。

编译设置

1. 设置DPS-SDK。

针对Android设备的编译环境,将SDK目录用软链接ln -s的方式放入Android源代码的external目

录下,并修改platform/device目录的相应产品目录下的device.mk,增加如下一行:

$(call inherit-product-if-exists,external/dps-sdk/dps_sdk.mk)

2. 部署安全策略。

需要手动加入 DPS 对部分原生 Android 服务的 sepolicy 和 seccomp 补丁,具体方法为手动

执行external/dps-sdk/policy/update_sepolicy.sh [android_home]和external/dps-sdk/

policy/update_seccomp_policy.sh [android_home]。

其中,[android_home]代表Android源码跟路径。

如果在集成开发环境当中出现因为SELinux Policy阻碍编译以及在编译之后运行过程中产

生SELinux permissive审计日志,请根据external/dps-sdk/policy/sepolicy/当中的dps_file_c

ontexts和dps.te文件进行SELinux策略的补充和调整。

3. 编译镜像。

准备就绪之后,对Android产品镜像进行正常编译,DPS就可以随产品镜像一同生成了。

高阶的DPS配置可以在external/dps-sdk/dps_sdk.mk中进行具体的控制。

内核配置

开发者如果需要为目标设备编译Linux Kernel,请确保Linux Kernel版本在3.15及以上。并且需要检

查在Kernel编译的defconfig选项中使能了以下项目。

• 开启AUDIT和NETLINKE

CONFIG_AUDIT_ARCH=yCONFIG_AUDIT=yCONFIG_HAVE_ARCH_AUDITSYSCALL=yCONFIG_AUDITSYSCALL=yCONFIG_AUDIT_WATCH=yCONFIG_AUDIT_TREE=yCONFIG_NF_CT_NETLINK=yCONFIG_NF_CT_NETLINK_TIMEOUT=yCONFIG_NETFILTER_NETLINK_GLUE_CT=y

• 开启NETFILTER和IPTABLES

CONFIG_NETFILTER=yCONFIG_NETFILTER_NETLINK=yCONFIG_NETFILTER_NETLINK_ACCT=y

文档版本:20200417 891

Page 904: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

CONFIG_NETFILTER_NETLINK_QUEUE=yCONFIG_NETFILTER_NETLINK_LOG=yCONFIG_IP_NF_IPTABLES=y

• 开启XTABLES及相关选项

CONFIG_NETFILTER_XTABLES=y

## Xtables combined modules#CONFIG_NETFILTER_XT_MARK=y...

## Xtables targets#CONFIG_NETFILTER_XT_TARGET_AUDIT=y...

## Xtables matches#CONFIG_NETFILTER_XT_MATCH_BPF=y...

编译示例

DPS模块提供头文件和静态库供设备应用集成使用。AppSample为实现参考。

• external/dps/client/inc/DPSClient.h

DPS client header file

• libdspclient.a

DPS client static library

• libiotx.a

Link MQTT static library

Android.bp示例:

cc_binary { name: "AppSample", include_dirs: [ "external/dps/client/inc", ... ], srcs: [ "AppSample.cpp", ... ], static_libs: [ "libiotx", "libdpsclient", ... ],

892 文档版本:20200417

Page 905: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

}

启动设置

对于Android 7以上版本,目前DPS在Android设备上通过集成编译即可自启动,无需额外配置。

对于Android 5,需要在系统的init.rc或者厂商自定义的init.<vendor>.rc当中声名DPS服务。声名方

式如下。

service dpsd /system/bin/dps/bin/dpsd class main

5.2.4 服务配置本章主要介绍设备保护服务SDK的服务配置。

DPS服务的配置文件位于SDK的packages目录下,文件名为configure.ini,此配置文件保存DPS服

务程序的基本配置,其中:

• DPS_DATA:DPS服务器程序存放数据的路径,请配置到操作系统的可读/写分区的文件夹路径

下。

• SYSTEM_VERSION:用以配置设备固件版本。配置方法如下所示。

- 如果设备厂商始终使用本地文件系统来追溯固件版本,那么请选择textfile比对方式。例如:

SYSTEM_VERSION=version://textfile:/etc/YOUR_VERNO_FILE:.+

其中/etc/YOUR_VERNO_FILE代表厂商固件版本号寄存的文本文件路径,.+代表正则表达

式,用以从该文件路径中解析版本号。

- 如果想使用字串当做固件版本号,请选择string比对方式。例如:

SYSTEM_VERSION=version://string:ver.1.0.0

其中ver.1.0.0即为版本号。

注意:

固件版本号会影响在目标设备进行固件升级之后需要重新取证等功能,请务必在固件开发过程

中根据即将发布的固件版本修改此配置项,否则将对目标设备造成严重的后果。

• PROTECTED_PATH:目标设备取证扫描的自定义路径,在此路径之下的所有文件将被取证,建议

配置成目标设备上可执行程序、共享库、配置文件等重要文件存放的目录。

文档版本:20200417 893

Page 906: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

• DPS_DEBUG,NUM_LOGS 和 LOG_FILE_SIZE:DPS调试相关选项。配置方法如下所示。

- DPS_DEBUG表示DPS的调试开关,默认为关闭0,如果需要打开,请配置成1。

- NUM_LOGS表示DPS调试开关在打开的情况下,DPS旧日志保存的数目,默认为3个。

- LOG_FILE_SIZE表示DPS调试开关在打开的情况下,每个DPS日志文件的最大尺寸,默认为10

MB。

configure.ini示例:

[system]DPS_DATA=/data/dps DPS_PROFILE=server DPS_DEBUG=1NUM_LOGS=3 LOG_FILE_SIZE=10240

[attestation]PROTECTED_PATH=

[device]SYSTEM_VERSION=version://textfile:/etc/FW_VERSION:.+ MANAGED_ID=managedid://textfile:/etc/MANAGED_ID:.+

5.2.5 客户端API本章主要介绍设备保护服务SDK的客户端API。

概述

DPS是自包含服务,不需要额外的开发和编译,SDK含预编译客户端可与安全运营中心互动消息和控

制。此外,SDK依然提供客户端API使设备应用将自有上云通分享给DPS使用,无需另外建立网络连

接。

客户端API有两种集成方法,C版本API和C++版本API。基础C版本API让DPS复用应用上云通道;C+

+版本API则抽象化DPS的接入方式,使其他应用能模仿DPS与应用对接,分享上云通道。

C版本API

C版本API架构图如下所示。

894 文档版本:20200417

Page 907: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

C版本API让DPS服务复用上云通道,上云通道为具备有和服务器连接能力的协议。C版本API可参考

的SDK文件如下。

• include/dps_core.h:列出应用对接DPS所需接口。

• example/client-sample/main.c:使用dps_core.h配合Linkkit MQTT上云完成的应用范例。

应用透过dps_init初始化与DPS服务的通讯句柄。

void* dps_init(const char *product_key, const char *device_key);

应用透过dps_connection注册消息处理器,此处理器当DPS消息到来时被调用,您可在处理器中将

DPS消息发送往服务器,或者存到队列等待后续发送。

typedef bool (*pub_handle)(const char *, const char *, int , void *);

void dps_connection(void *session, pub_handle pub_topic, void *context);

当您确认上云通道一切就绪时,即可透过dps_on_connected告知DPS,此时DPS服务即可使用此通

道将消息发往服务器端,抵达安全运营中心。

bool dps_on_connected( void *session);

当您发现有来自安全运营中心的消息,即可透过dps_on_message直接将消息传送给DPS服务。

注意:

文档版本:20200417 895

Page 908: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

此API需在dps_on_connected调用之后,确保DPS服务认为上云通道畅通。

bool dps_on_message( void *session, const char *message, int length);

终止服务。

void dps_final(void *session)

C++版本API

C++版本API使各种应用能模仿DPS与应用对接的方式,共同分享上云通道。

C++版本API可参考的SDK文件如下。

• include/DPSClient.h:以下做说明。

• example/cloud-agent/*:使用 DPSClient.h 配合 Linkkit MQTT 上云完成的应用范例。

DPSConnection类:

DPS用来上云的消息通道抽象接口。应用需要继承并实现此接口,使DPS客户端可以复用应用的上云

通道。

enum DPSConnectionStatus{ DPS_CONNECTION_DISCONNECTED = 0, DPS_CONNECTION_CONNECTED,};

class DPSConnectionClient{public: virtual ~DPSConnectionClient();

virtual bool onMessage( const char *message, int length) = 0; virtual bool onConnectionStatus( DPSConnectionStatus status) = 0;};

896 文档版本:20200417

Page 909: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

class DPSConnection{public: virtual ~DPSConnection();

virtual bool subscribe(const char * topic) = 0; virtual bool publish(const char *topic, const char *event, int length) = 0;};

DPSClient类:

应用和DPS客户端交互的接口。

class DPSClient : public DPSConnectionClient{public: DPSClient( const char *product_key, const char *device_key);

static DPSClient *create(const char *product_key, const char * device_name);

/* DPSConnectionClient implements */ bool onMessage( const char *message, int length); bool onConnectionStatus( DPSConnectionStatus satus);};

代码示例如下所示。

• AppSampleConnection.h

#include "DPSClient.h"class AppSampleConnection : public DPSConnection {public: AppSampleConnection( DPSClient *client);

bool subscribe(const char * topic); bool publish(const char *topic, const char *event, int length);

private: DPSClient *mClient; enum ConnectionState { CONNECTED, CLOSED, } mState; ...};

• AppSampleConnection.cpp

#include "AppSampleConnection.h"/** * DPS publishs events to the cloud. * /bool AppSampleConnection::subscribe(const char *topic){...}

/** * DPS subscribes a event topic.

文档版本:20200417 897

Page 910: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

* /bool AppSampleConnection::publish(const char *topic, const char *event, int length){...}

1. 创建DPSClient实例,并开始服务。

#include "DPSClient.h"const char *product_key = "sample";const char *device_name = "test-1";DPSClient *client = DPSClient.create(product_key, device_name);

AppSampleConnection *connection = new AppSampleConnection(client);client.start( connection);

// MQTT messaging loop...

2. 分发处理DPS消息。

char message[DPS_MESSAGE_MAX_LENGTH];...// Application received a new message with length...mClient->onMessage(message, length);

5.3 设备取证服务SDK

5.3.1 概览设备取证服务Device Attestation Service(以下简称为DAS), 是为运行RTOS的物联网节点设备提

供的安全审计服务。DAS会实时上报运行状态,定期检查系统的完整性,让管理者随时了解设备的安

全状况,及时发现、排查和修复安全问题。

DAS分Core、Platform、Service 三个层次提供应用集成,平台移植和服务扩展功能,旨在方便各种

设备利用SOC服务一站式保护物联网终端节点安全。

898 文档版本:20200417

Page 911: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

下载SDK

设备端 版本号 发布时间 使用环境 版本说明

DAS 1.0.1 2018-12-25 RTOS • 上报运行状态• 定期检测系统完整性

开发环境

DAS是以开源代码方式提供,用户无需额外配置开发环境,只需要根据目标系统的开发要求将SDK解

压到特定位置即可。

DAS同时是作为AliOS Things的一个安全组件发布的,代码位于/security/das目录下,开发者可以

直接使用。

5.3.2 应用集成在一般设备的实际开发中,由于资源受限,每个设备网络连接的数目是受限的。DAS充分考虑到这

点,在核心层只定义了DAS相关数据的订阅和分发接口,设备可以根据实际的网络会话上对接DAS服

务。

初始化核心服务

void* das_init(const char *product_name, const char *device_name);

设置上下行消息主题

const char* das_pub_topic(void *session,const char *topic);

文档版本:20200417 899

Page 912: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

const char* das_sub_topic(void *session, const char *topic);

说明:

如果不单独设置主题,DAS使用缺省主题。

配置网络连接

typedef int (*publish_handle_t)(const char *topic, const uint8_t *message, size_t msg_size, void *channel);

void das_connection(void *session, publish_handle_t publish_handle, void *channel);

更新连接状态

void das_on_connected(void *session);

void das_on_disconnected(void *session);

void das_on_message(void *session, const uint8_t *message, size_t msg_size);

步进驱动取证服务

das_result_t das_stepping(void *session, uint64_t now);

说明:

如果适配定时器函数,则DAS服务缺省由定时器任务驱动。

终止核心服务

void das_final(void *session);

综合示例代码

本示例是基于阿里云Link Kit MQTT的代码片段,完整代码见DAS开发库MQTT示例。

#include "iot_import.h"

#define PRODUCT_KEY "demo_das_product"#define DEVICE_NAME "demo_das_device_1"

static void *session = null;

static int _on_publish( const char *topic, uint8_t *msg, uint32_t size, void *mqtt){ iotx_mqtt_topic_info_t topic_msg; topic_msg.qos = IOTX_MQTT_QOS1; topic_msg.payload = (void *)message; topic_msg.payload_len = length; return IOT_MQTT_Publish( mqtt, topic, &topic_msg);}

900 文档版本:20200417

Page 913: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

static void on_message( void *handle, void *pclient, iotx_mqtt_event_msg_pt msg){ das_on_message( session, msg.payload, msg.payload_len); }

int main( int argc, const char argv[][]){ const char *sub_topic;

mqtt = IOT_MQTT_Construct( &mqtt_params);

session = das_init( PRODUCT_KEY, DEVICE_NAME);

das_connection(session, _on_publish, mqtt);

das_on_connected(session);

sub_topic = das_sub_topic(session, NULL);

IOT_MQTT_Subscribe( mqtt, sub_topic, IOTX_MQTT_QOS1, on_message, session);

while (IOT_MQTT_Yield(mqtt, 200) != IOT_MQTT_DISCONNECTED) { ... das_stepping(session, time(NULL)); ... }

das_on_disconnected(session); das_final(session);

return 0;}

5.3.3 平台、设备与服务适配本章主要介绍设备取证服务的平台适配、设备适配和ROM度量服务适配。

平台适配

DAS仅使用到少数几个libc标准函数(strlen、memcpy、memset)和数据类型定义(size_t、

uint8_t、uint32_t、uint64_t)。

如果设备平台没有相关实现或有不同的定义,可以通过在Makefile中设置CONFIG_DAS_PLATFORM_

ALT替代头文件,然后在替代头文件中实现或重定义DAS所需的函数和类型。

Makefile示例如下:

CONFIG_DAS_PLATFORM_ALT = platform_alt.h

设备适配

设备适配的函数定义在inc/das/hardware.h文件中。

文档版本:20200417 901

Page 914: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

• 获取设备固件版本

size_t das_hal_firmware_version(char *buf, size_t size);

• 获取设备硬件标识

size_t das_hal_device_id(char *buf, size_t size);

ROM度量服务适配

作为DAS缺省的安全度量服务,ROM Service完成设备代码完整性的检查功能,需要设备适配ROM(

txt段)的分段信息。

typedef struct _das_rom_bank { uint8_t* address; size_t size;} das_rom_bank_t;

int das_hal_rom_info(das_rom_bank_t banks[DAS_ROM_BANK_NUMBER]);

ROM度量服务可以通过修改inc/das/configure.h中DAS_SERVICE_ROM_ENABLED的定义来禁用。

5.3.4 服务扩展除了使用DAS自带的安全度量服务以外, 您还可以根据设备的特点和需要在DAS服务框架内构建自己

的度量服务。

实现服务

在src/service下创建service_skeleton.c文件,并实现inc/das/service.h中的服务接口定义。

das_result_t skt_info (char *buffer, size_t size, das_service_state_t *state);das_result_t skt_attest (char *path, size_t size, das_sum_context_t *sum_context, das_service_state_t *state);das_result_t skt_measure (das_sum_context_t *sum_context, das_mac_context_t *mac_context, das_service_state_t *state);

das_service_t skt_service = { .name = "skeleton", .info = skt_info, .attest = skt_attest, .measure = skt_measure, };

添加服务

在src/service/service.c文件中添加服务。

#if DPS_SERVICE_SKELETON_ENABLEDextern das_service_t skt_service;#endif

das_service_t * das_service_table[DAS_MAX_SRV_NUM] = {

902 文档版本:20200417

Page 915: 阿里云IoT Link Rack 一体机

开发指南 /  5 物联网安全运营中心

#ifdef DPS_SERVICE_SKELETON_ENABLED &skt_service,#endif &sys_srv, NULL,};

配置服务

配置Makefile使能服务。

CFLAGS += -DDPS_SERVICE_SKELETON_ENABLEDSRCS += service/service_skeleton.c

文档版本:20200417 903