本文介绍Link SDK的功能和对接使用说明。
SDK功能说明
类型 | 功能模块 | 功能说明 |
设备接入 | MQTT接入 | 将设备与物联网平台建立MQTT协议的连接,实现设备与物联网平台的通信。 |
一型一密、一机一密 | 支持通过设备密钥的方式对设备进行认证。 支持动态注册的方式对设备进行认证。 | |
设备管理 | 物模型 | 基于物模型对设备进行管理,无需关心设备与物联网平台之间的数据交互格式,降低开发成本。 |
NTP服务 | 设备获取当前物联网平台的时间。 | |
网关与子设备 | 将设备的网关接入物联网平台,使不具备IP地址的设备间接地接入物联网平台。 | |
设备绑定 | 二维码配网 | |
绑定、重置 | 支持将设备绑定到某一用户名下。 支持重置设备的绑定关系。 | |
设备运维 | OTA升级 | 设备通过物联网平台实现设备端的升级。
|
文件结构说明
使用命令tree linkkit,可以查看linkkit的文件内容如下:
linkkit
|-- export # 对外头文件文件夹
| |-- iot_export.h
| |-- iot_export_awss.h
| |-- iot_export_diagnosis.h
| |-- iot_export_errno.h # 错误码头文件
| |-- iot_export_event.h
| |-- iot_export_linkkit.h # 主要的mqtt操作接口头文件
| |-- iot_export_ota.h # OTA功能头文件
| |-- iot_export_reset.h # 重置头文件
| `-- iot_export_shadow.h
|-- import # 部分需要开发者实现的头文件和实现实例文件夹
| |-- iot_import_product.c # OTA等功能需要开发者实现的实例代码
| `-- iot_import_product.h # OTA等功能需要开发者实现的头文件
`-- liblink_kit.a
设备接入
注册需要关注的消息回调。
# 例如,注册设备的上线消息回调。 static int user_connected_event_handler(const void *dev, int dev_num) { ... return 0; } IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);
设置ProductKey、ProductSecret、DeviceName和DeviceSecret信息。
设置主设备ProductKey、ProductSecret、DeviceName和DeviceSecret信息。
iotx_linkkit_dev_meta_info_t master_meta_info; memset(&master_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t)); master_meta_info.product_key = PRODUCT_KEY; master_meta_info.product_secret = PRODUCT_SECRET; master_meta_info.device_name = DEVICE_NAME; master_meta_info.device_secret = DEVICE_SECRET; int master_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_MASTER, &master_meta_info);
如果主设备为网关设备,需要设置子设备信息。
iotx_linkkit_dev_meta_info_t slave_meta_info; memset(&slave_meta_info, 0, sizeof(iotx_linkkit_dev_meta_info_t)); slave_meta_info.product_key = sub_dev_product_key; slave_meta_info.device_name = sub_dev_device_name; int slave_devid = IOT_Linkkit_Open(IOTX_LINKKIT_DEV_TYPE_SLAVE, &slave_meta_info);
开始连接到服务器。
若由于网络等原因连接失败,会不断进行重试,直到成功。
do { res = IOT_Linkkit_Connect(); if (res < 0) { EXAMPLE_TRACE("IOT_Linkkit_Connect failed, retry after 5s...\n"); usleep(5000 * 1000); } } while (res < 0);
创建线程,轮询消息。
# 线程中执行 while (1) { IOT_Linkkit_Yield(USER_EXAMPLE_YIELD_TIMEOUT_MS); }
需要结束时,先退出线程,再释放相应的资源。
/* 等待线程退出,并释放线程资源,也可用分离式线程,但需要保证线程不使用linkkit资源后,再去释放linkkit */ while (g_thread_not_quit) { usleep(20 * 1000); } pthread_join(g_thread, NULL); IOT_Linkkit_Close(master_devid);
在上述流程中,推荐或者必须要注册的回调函数及其功能说明如下:
/* 注册链接状态的回调 */
IOT_RegisterCallback(ITE_CONNECT_SUCC, user_connected_event_handler);
IOT_RegisterCallback(ITE_DISCONNECTED, user_disconnected_event_handler);
/* 注册消息通知 */
IOT_RegisterCallback(ITE_LINK_VISUAL, user_link_visual_handler);//linkvisual自定义消息
IOT_RegisterCallback(ITE_SERVICE_REQUST, user_service_request_handler);//物模型服务类消息
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_handler);//物模型属性设置
IOT_RegisterCallback(ITE_TIMESTAMP_REPLY, user_timestamp_reply_handler);//NTP时间
IOT_RegisterCallback(ITE_FOTA, user_fota_handler);//固件OTA升级事件
物模型
物模型是阿里云物联网平台为产品定义的数据模型,用于描述产品的功能。本文介绍物模型相关概念和使用限制。更多信息请参考什么是物模型。
上报属性
IOT_Linkkit_Report(auth->dev_id, ITM_MSG_POST_PROPERTY, (unsigned char *)value, strlen(value));
设置属性
当云端发起设置属性时,设备端会在回调中收到该消息,开发者可以据此做相应的处理。
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_handler);//物模型属性设置
static int user_property_set_handler(const int devid, const char *request, const int request_len) {
printf("Property Set Received, Devid: %d, Request: %s\n", devid, request);
}
调用服务
服务是指可供外部调用的指令或方法。服务调用中可设置输入和输出参数。当云端发起同步服务请求时,设备端会在回调中收到该消息,开发者可以据此做相应的处理。
IOT_RegisterCallback(ITE_SERVICE_REQUST, user_service_request_handler);//物模型服务类消息
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_handler);//物模型属性设置
static int user_service_request_handler(const int devid, const char *id, const int id_len,
const char *serviceid, const int serviceid_len,
const char *request, const int request_len,
char **response, int *response_len) {
printf("Service Request Received, Devid: %d, ID %.*s, Service ID: %.*s, Payload: %s\n",
devid, id_len, id, serviceid_len, serviceid, request);
}
上报事件
事件是指设备运行时,主动上报给云端的信息,一般包含需要被外部感知和处理的信息、告警和故障。当设备需要上报事件时,通过以下代码可以直接上报。
int IOT_Linkkit_TriggerEvent(int devid, char *eventid, int eventid_len, char *payload, int payload_len);
LinkVisual消息
Linkvisual消息是视频业务的消息,用于辅助Linkvisual SDK进行音视频服务业务处理,开发者仅需要将消息按一定规则传递给LinkVisual SDK即可。
static int user_service_request_handler(const int devid, const char *id, const int id_len,
const char *serviceid, const int serviceid_len,
const char *request, const int request_len,
char **response, int *response_len) {
printf("Service Request Received, Devid: %d, ID %.*s, Service ID: %.*s, Payload: %s\n",
devid, id_len, id, serviceid_len, serviceid, request);
/* 部分物模型服务消息由LinkVisual处理,部分需要自行处理。 */
int link_visual_process = 0;
for (unsigned int i = 0; i < sizeof(link_visual_service)/sizeof(link_visual_service[0]); i++) {
/* 这里需要根据字符串的长度来判断 */
if (!strncmp(serviceid, link_visual_service[i], strlen(link_visual_service[i]))) {
link_visual_process = 1;
break;
}
}
if (link_visual_process) {
/* ISV将某些服务类消息交由LinkVisual来处理,不需要处理response */
/* 此处请注意:需要使用devid准确查询出实际的设备证书(ProductKey、DeviceName、DeviceSecret) */
lv_device_auth_s auth;
GetAuth(devid, &auth);
lv_message_adapter_param_s in = {0};
in.type = LV_MESSAGE_ADAPTER_TYPE_TSL_SERVICE;
in.msg_id = (char *)id;
in.msg_id_len = id_len;
in.service_name = (char *)serviceid;
in.service_name_len = serviceid_len;
in.request = (char *)request;
in.request_len = request_len;
int ret = lv_message_adapter(&auth, &in);
if (ret < 0) {
printf("LinkVisual process service request failed, ret = %d\n", ret);
return -1;
}
} else {
/* 非LinkVisual消息由客户自行处理即可 */
...
}
return 0;
}
OTA
SDK提供OTA通道,用于更新设备的固件版本。开发者需要按以下步骤来使用OTA。
配置固件版本号。
# 在文件import/iot_import_product.c中修改版本号信息,注意:SDK启动后,会自动上报该版本号信息至云端 int HAL_GetFirmwareVersion(char version[FIRMWARE_VERSION_MAXLEN]) { memset(version, 0x0, FIRMWARE_VERSION_MAXLEN); strncpy(version, "1.0", FIRMWARE_VERSION_MAXLEN); version[FIRMWARE_VERSION_MAXLEN - 1] = '\0'; return strlen(version); }
在控制台配置新的固件版本和版本号信息。
在控制台上触发固件版本下载。
当控制台触发估计版本下载后,设备端SDK会自动下载固件,并写入到设备的某个路径。路径的配置方式如下:
#define otafilename "/tmp/alinkota.bin" void HAL_Firmware_Persistence_Start(void) { fp = fopen(otafilename, "w"); assert(fp); return; }
固件下载完成后,开发者可以使用新的固件进行更新。
更新完成后,SDK重新启动,则会上报新的版本号信息,OTA成功。