公寓智能门锁接入及使用实践
更新时间:2020-01-03 13:32:56
本文适用于智能门锁的运营方,智能门锁(直接或间接-门锁网关)使用物联网人居平台的密码锁安全服务。此处以智能公寓锁网关为例说明了如何对接设备端,服务端,人居平台北向API(门锁服务API)。
方案介绍
公寓密码锁设备版架构:
公寓密码锁网关版架构:
核心能力
ID²设备安全认证
轻量级安全协议iTLS
门锁密码管理服务(固定密码和动态密码)
适用范围:
智能门锁直连人居平台
智能门锁通过门锁网关连接到人居平台
公寓锁业务流程
公寓锁网关对接说明
1,服务端对接
1.1,创建产品,自定义物模型
1,进入智能生活平台(飞燕平台) ,初始化 “创建新项目”
2,进入新项目,暂时“创建新产品”,请注意以下选项:
官员类型:
- 网关版对接时:选择“网关”
- 设备版对接时:选择“设备”
所属分类:
- 网关版对接时:选择
- 设备版对接时:选择“家居安防-智能门锁”
使用ID²认证:是
网关版对接时配置:
设备版对接时配置:
3,创建产品成功后获得对应的ProductKey。
1.2,自定义物模型
人居平台的公寓锁物模型,是在智能门锁物模型基础上自定义的。
1,进入智能生活平台(飞燕平台) -选择项目-选择产品,在“自定义”模块中插入“添加功能”:
网关版对接时:在网关类产品中添加“自定义对象模型”。
设备版对接时:在设备类产品中添加“自定义对象模型”。
以设备版对接为例:
2,按照《公寓锁物模型》添加自定义功能:
- 下载《公寓锁物模型》。
以设备版对接为例:
1.3,检查ID²激活授权
登录“ IoT设备身份认证(ID²)控制台 ”,使用管理->产品管理-> [选择指定产品]查看,检查“授权信息”是否有效。如果授权信息为空或未激活的授权为0,请购买ID²使用授权。
2,设备端对接
网关版对接时:在网关上进行适配和对接。
设备版对接时:在门锁设备上进行适应和对接。
2.1设备端对接流程:
PS:
如果您的门锁通过智能生活(飞燕),智能人居接入,那么您可以忽略“ STEP2服务端对接”。
推荐您通过2.3、2.4章节的内容完成ID²的适应。如果您需要了解更多的细节,请参考:《ID²设备厂商接入流程》。
2.2设备端架构:
2.3获取SDK
2.4设备端适配-集成SDK
查看:Link Kit SDK v3.0.x集成ID²手册
- 安全SDK的临时若为纯软实现即安全沙箱方案,需要开发者提供硬件芯片开发环境的编译工具链,操作系统版本,CPU模型,我方技术通讯先进行逐步编译并提供替代库给开发者。这个步骤需要在钉钉群内完成对接。
2.5物模型对接
- 使用Link Kit SDK进行物模型编程的说明:C SDK,NodeJS SDK,Java SDK,Python SDK。
3,人居平台北向API对接(门锁服务API)
查看:门锁服务API手册
附录:设备端示例代码
主要提供人居平台的公寓锁物模型,在设备端调用ID²Client SDK处理静态密码部分的示例代码。
- 获取id2-id-GetID2Id:
int sample_get_id2_id(void)
{
irot_result_t ret;
uint32_t id2_len = ID2_ID_LEN;
uint8_t id2[ID2_ID_LEN + 1] = {0};
ret = id2_client_init();
if (ret != IROT_SUCCESS) {
printf("id2 client init fail, %d\n", ret);
return -1;
}
ret = id2_client_get_id(id2, &id2_len);
if (ret != IROT_SUCCESS) {
printf("get client id2 fail, %d\n", ret);
goto _out;
}
_out:
id2_client_cleanup();
return ret == IROT_SUCCESS ? 0 : -1;
}
- 获取挑战字安全码-GetID2AuthCode:
根据下发的挑战字(challenge),调用ID²Client接口,生成挑战字安全码。
int sample_get_id2_auth_code(const char *challenge)
{
irot_result_t ret;
uint32_t auth_code_len = 256;
uint8_t auth_code[256] = {0};
if (challenge == NULL) {
printf("invalid input arg\n");
return -1;
}
ret = id2_client_init();
if (ret != IROT_SUCCESS) {
printf("id2 client init fail, %d\n", ret);
return -1;
}
ret = id2_client_get_challenge_auth_code(
challenge, NULL, 0, auth_code, &auth_code_len);
if (ret != IROT_SUCCESS) {
printf("get challenge auth code fail, %d\n", ret);
goto _out;
}
_out:
id2_client_cleanup();
return ret == IROT_SUCCESS ? 0 : -1;
}
- 添加静态密码-AddPin:
调用ID²客户端接口解密密码和rule密文,在调用ID²解密接口前,需先将密文由Base64转换成16进制。
static int _base64_decode(const uint8_t* input, uint32_t input_len,
uint8_t* output, uint32_t* output_len)
{
//TODO to be implemented
return 0;
}
int sample_id2_decrypt_password(const char *password)
{
irot_result_t ret;
uint32_t hex_len = 0;
uint32_t out_len = 0;
uint8_t *hex_data = NULL;
uint8_t *out_data = NULL;
if (password == NULL) {
return -1;
}
hex_len = strlen(password);
hex_data = malloc(hex_len);
if (hex_data == NULL) {
printf("out of mem, %d\n", hex_len);
return -1;
}
ret = _base64_decode((uint8_t *)password, strlen(password), hex_data, &hex_len);
if (ret < 0) {
printf("base64 decode fail\n");
free(hex_data);
return -1;
}
out_len = hex_len;
out_data = malloc(out_len);
if (out_data == NULL) {
printf("out of mem, %d\n", out_len);
return -1;
}
ret = id2_client_init();
if (ret != IROT_SUCCESS) {
printf("id2 client init fail, %d\n", ret);
goto _out;
}
ret = id2_client_decrypt(hex_data, hex_len, out_data, &out_len);
if (ret != IROT_SUCCESS) {
printf("id2 client decrypt fail, %d\n", ret);
goto _out;
}
_out:
if (hex_data != NULL) {
free(hex_data);
}
if (out_data != NULL) {
free(out_data);
}
id2_client_cleanup();
return ret == IROT_SUCCESS ? 0 : -1;
}
int sample_id2_decrypt_rule(char *rule)
{
irot_result_t ret;
uint32_t hex_len = 0;
uint32_t out_len = 0;
uint8_t *hex_data = NULL;
uint8_t *out_data = NULL;
if (rule == NULL) {
return -1;
}
hex_len = strlen(rule);
hex_data = malloc(hex_len);
if (hex_data == NULL) {
printf("out of mem, %d\n", hex_len);
return -1;
}
ret = _base64_decode((uint8_t *)rule, strlen(rule), hex_data, &hex_len);
if (ret < 0) {
printf("base64 decode fail\n");
free(hex_data);
return -1;
}
out_len = hex_len;
out_data = malloc(out_len);
if (out_data == NULL) {
printf("out of mem, %d\n", out_len);
return -1;
}
ret = id2_client_init();
if (ret != IROT_SUCCESS) {
printf("id2 client init fail, %d\n", ret);
goto _out;
}
ret = id2_client_decrypt(hex_data, hex_len, out_data, &out_len);
if (ret != IROT_SUCCESS) {
printf("id2 client decrypt fail, %d\n", ret);
goto _out;
}
_out:
if (hex_data != NULL) {
free(hex_data);
}
if (out_data != NULL) {
free(out_data);
}
id2_client_cleanup();
return ret == IROT_SUCCESS ? 0 : -1;
}
- 修改静态密码-UpdatePin:
同添加静态密码,调用ID²客户端接口解密密码和规则密文,示例代码参考如上。 - 设置静态密码规则-SetPinRule:
调用ID²客户端接口解密rule密文,示例代码参考AddPin中的“ sample_id2_decrypt_rule”函数。