LV02-01-天猫精灵IOT-06-linkkit-01-linkkit代码分析

本文主要是天猫精灵IOT linkkit——linkkit代码分析的相关笔记,若笔记中有错误或者不合适的地方,欢迎批评指正😃。

点击查看使用工具及版本
Windows版本 windows11
Ubuntu版本 Ubuntu22.04的64位版本
VMware® Workstation 16 Pro 16.2.3 build-19376536
终端软件 MobaXterm(Professional Edition v23.0 Build 5042 (license))
点击查看本文参考资料
分类 网址 说明
官方网站 阿里云 阿里云官网主页
阿里生活物联平台 生活物联网平台(飞燕平台)主页
AliGenie 天猫精灵开放平台AliGenie主页
阿里物联网平台 阿里物联网平台主页
Bluetooth 技术网站 蓝牙协议规范什么的可以来这里找
Telink Telink | Chips for a Smarter IoT (telink-semi.com)
Telink中文官网
开发手册 AliOS Things开发指南 AliOS Things开发指南,这里是最新版本,可以直接从官网找到
AliOS Things开发指南 AliOS Things应用开发指南,这里应该是3.3版本的完整开发文档
AliOS Things开发指南(3.0) AliOS Things应用开发指南,这里应该是3.0版本的完整开发文档
生活物联网平台开发文档 生活物联网平台(飞燕平台)开发文档
《设备端开发指南》
Wi-Fi IoT品类定义与功能开发 天猫精灵IoT开放平台——Wi-Fi IoT品类定义与功能开发
硬件平台 mk3080 WiFi开发板 WiFi开发板使用指南-阿里云开发者社区
esp8266开发板 一个教程:ESP8266-NodeMCU开发板详解-太极创客 (taichi-maker.com)
TLSR8258 Datasheet Datasheet for Telink BLE + IEEE802.15.4 MultiStandard Wireless SoC TLSR8258
参考资料 AliOS Things 3.0 应用开发指南 这个只是一篇参考文章,里面是一些环境搭建相关的,可以参考
IP知识百科 - 华为 (huawei.com) IP的一些相关知识点
点击查看相关文件下载
分类 网址 说明
蓝牙规范相关文档 Core Specification 5.2 核心规格 5.2,该规范定义了创建可互操作的Bluetooth 设备所需的技术。
《Core_v5.2.pdf》
Mesh Model(v1.1) 本Bluetooth 规范定义了模型(以及它们所需的状态和消息),这些模型用于在mesh 网络中的节点上执行基本功能,超出了Bluetooth Mesh 配置文件 规范中定义的基础模型。
本规范包括定义跨设备类型标准功能的通用模型,以及支持关键mesh 场景的模型,如照明控制、传感器、时间和场景。
《MshMDL_v1.1.pdf》
Mesh Profile(v1.0.1) 该Bluetooth 规范定义了基本要求,以实现可互操作的mesh 网络解决方案,用于Bluetooth 低能量无线技术。
《MshPRFv1.0.1.pdf》
Mesh Device Properties 本规范包含Bluetooth Mesh 配置文件 和Bluetooth Mesh 模型规范所要求的设备属性的定义。
但是跟之前的有些区别,我主要看的之前的版本:《MMeshDeviceProperties_v1.2.pdf》
GATT Specification Supplement GATT Specification Supplement | Bluetooth® Technology Website。
好像可以在线看:《GATT Specification Supplement》
Assigned Numbers GATT的一些类型定义可以在这里找。
AliOS Things alios-things/AliOS-Things Gitee上的AliOSThings SDK源码仓库
alibaba/AliOS-Things GitHub上的AliOSThings SDK源码仓库
天猫精灵蓝牙Mesh协议栈 alibaba-archive/genie-bt-mesh-stack GitHub上的天猫精灵蓝牙Mesh协议栈源码仓库。
之前是在alibaba/genie-bt-mesh-stack这个仓库。
写笔记的时候最新提交为faf523618a6a2560090fc423222b9db80984bb7a
蓝牙Mesh设备开发指南 阿里云生活服务平台开发手册——蓝牙设备开发一节中的内容

这一部分我们主要是分析 AOS_ADK_PATH/components/linkkit目录的代码。

一、联网代码分析

1. MQTT打开过程

1

函数调用逻辑关系如下:

1
2
MQTT 打开过程:
IOT_Linkkit_Open() -> _iotx_linkkit_master_open() -> iotx_dm_open() -> dm_client_open() ->iotx_cm_open() -> iotx_cm_open_mqtt()

这个过程结束,只是进行了MQTT协议的打开,还没有去连接阿里云。

2. 连接过程

2

连接过程函数调用逻辑如下(复制到记事本,全屏打开,有对齐):

1
2
3
4
连接过程:
IOT_Linkkit_Connect -> _iotx_linkkit_master_connect-> iotx_dm_connect -> dm_client_connect->iotx_cm_connect-> _mqtt_connect(iotx_cm_mqtt.c)->IOT_MQTT_Construct->wrapper_mqtt_connect->ipstack.connect=iotx_net_connect
-> iotx_dm_subscribe
->_mqtt_connect->MQTTConnect->iotx_mc_send_packet->ipstack.write

二、消息相关代码分析

1. 消息发送

3

函数调用逻辑如下:

1
2
发布消息:
user_post_property-> IOT_Linkkit_Report->iotx_dm_post_property->dm_mgr_upstream_thing_property_post->dm_msg_request->dm_client_publish->iotx_cm_pub->pub_func->_mqtt_publish->IOT_MQTT_Publish_Simple->wrapper_mqtt_publish->MQTTPublish->iotx_mc_send_packet

2. 订阅消息

4

相关函数调用逻辑如下:

1
2
订阅消息:
IOT_Linkkit_Connect -> _iotx_linkkit_master_connect-> iotx_dm_subscribe->dm_server_subscribe_all->dm_client_subscribe->iotx_cm_sub->_mqtt_sub->IOT_MQTT_Subscribe->wrapper_mqtt_subscribe->MQTTSubscribe->iotx_mc_send_packet

3. 数据接收

3.1 IOT_RegisterCallback()函数

我们前面知道 AOS_SDK_PATH/application/example/linkkit_demo/linkkit_example_solo.c中这个函数是用于接收阿里云下发的数据的:

1
2
3
4
5
6
7
8
9
10
11
12
/** recv event post response message from cloud **/
static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
{
int res = 0;
EXAMPLE_TRACE("Property Set Received, Request: %s", request);

res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY,
(unsigned char *)request, request_len);
EXAMPLE_TRACE("Post Property Message ID: %d", res);

return 0;
}

这个回调函数在哪里被注册?我们看一下AOS_SDK_PATH/application/example/linkkit_demo/linkkit_example_solo.c中的linkkit_main()函数,会发现这个函数在这里被注册:

1
2
3
4
5
6
7
8
9
10
11
int linkkit_main(void *paras)
{
//......

/* Register Callback */
//......
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);
//......
return 0;
}

我们找一下这个IOT_RegisterCallback(),会发现这个函数是一个宏,定义在AOS_SDK_PATH/include/linkkit/infra/infra_compat.h中:

1
2
3
4
5
6
7
8
9
#define IOT_RegisterCallback(evt, cb)           iotx_register_for_##evt(cb)
#define DECLARE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb);
#define DEFINE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb) { \
if (evt < 0 || evt >= sizeof(g_impl_event_map)/sizeof(impl_event_map_t)) {return -1;} \
g_impl_event_map[evt].callback = (void *)callback;return 0;}

//......
DECLARE_EVENT_CALLBACK(ITE_PROPERTY_SET, int (*cb)(const int, const char *, const int))
//......

我们知道宏中##表示拼接,所以有:

1
2
3
4
5
IOT_RegisterCallback(ITE_PROPERTY_SET, user_property_set_event_handler);
// 由传入参数可以得到上面三个宏展开为

//#define IOT_RegisterCallback(evt, cb) iotx_register_for_##evt(cb)
iotx_register_for_ITE_PROPERTY_SET(user_property_set_event_handler)

会发现这三个宏展开后都一样,我们直接追踪iotx_register_for_ITE_PROPERTY_SET()这个函数会追踪到这个函数:

1
2
3
4
5
// OS_SDK_PATH/core/mk/syscall/usyscall/linkkit_usyscall.c
int iotx_register_for_ITE_PROPERTY_SET(int (*callback)(const int, const char *, const int))
{
return _IOT_RegisterCallback(ITE_PROPERTY_SET, (void*)callback);
}

但是实际上SDK并没有调用这个函数,这那它在别的地方还有定义?我们看上面的几个宏,长得基本一样,我们关注一下DECLARE_EVENT_CALLBACK这个宏,它在AOS_SDK_PATH/include/linkkit/infra/infra_compat.h声明了一系列函数,我们展开一下:

1
2
3
4
// AOS_SDK_PATH/include/linkkit/infra/infra_compat.h
DECLARE_EVENT_CALLBACK(ITE_PROPERTY_SET, int (*cb)(const int, const char *, const int))
// 展开为
int iotx_register_for_ITE_PROPERTY_SET(int (*cb)(const int, const char *, const int));

发现与前面函数同名了,实际上我们使用的就是这个,只是这里只是声明,它定义在哪?我们这个时候再来看一下DEFINE_EVENT_CALLBACK这个宏,我们发现它的evt参数若是ITE_PROPERTY_SET,那么展开后,其实跟上面也是一样的:

1
2
3
#define DEFINE_EVENT_CALLBACK(evt, cb)          int iotx_register_for_##evt(cb) { \
if (evt < 0 || evt >= sizeof(g_impl_event_map)/sizeof(impl_event_map_t)) {return -1;} \
g_impl_event_map[evt].callback = (void *)callback;return 0;}

有没有这个宏声明的函数?我们搜索一下,发现是有的,我们打开AOS_SDK_PATH/components/linkkit/infra/infra_compat.c,会发现也有一样的定义:

1
DEFINE_EVENT_CALLBACK(ITE_PROPERTY_SET,         int (*callback)(const int, const char *, const int))

所以综合起来,就相当于iotx_register_for_ITE_PROPERTY_SET()函数在AOS_SDK_PATH/components/linkkit/infra/infra_compat.c被定义,在AOS_SDK_PATH/include/linkkit/infra/infra_compat.h中被声明,所以,这个函数实际的定义是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// AOS_SDK_PATH/components/linkkit/infra/infra_compat.c
#define DEFINE_EVENT_CALLBACK(evt, cb) int iotx_register_for_##evt(cb) { \
if (evt < 0 || evt >= sizeof(g_impl_event_map)/sizeof(impl_event_map_t)) {return -1;} \
g_impl_event_map[evt].callback = (void *)callback;return 0;}
// 展开后可得函数定义为
int iotx_register_for_ITE_PROPERTY_SET(int (*callback)(const int, const char *, const int)))
{
if (evt < 0 || evt >= sizeof(g_impl_event_map)/sizeof(impl_event_map_t))
{
return -1;
}
g_impl_event_map[ITE_PROPERTY_SET].callback = (void *)callback;
return 0;
}

3.2 数据接收

5

相关函数调用逻辑如下:

1
2
数据接收 
IOT_Linkkit_Yield->iotx_dm_dispatch->_iotx_linkkit_event_callback->user_property_set_event_handler